diff options
Diffstat (limited to 'sanei')
| -rw-r--r-- | sanei/Makefile.am | 2 | ||||
| -rw-r--r-- | sanei/Makefile.in | 704 | ||||
| -rw-r--r-- | sanei/sanei_DomainOS.c | 2 | ||||
| -rw-r--r-- | sanei/sanei_DomainOS.h | 1 | ||||
| -rw-r--r-- | sanei/sanei_ab306.c | 4 | ||||
| -rw-r--r-- | sanei/sanei_access.c | 18 | ||||
| -rw-r--r-- | sanei/sanei_auth.c | 2 | ||||
| -rw-r--r-- | sanei/sanei_config.c | 10 | ||||
| -rw-r--r-- | sanei/sanei_config2.c | 2 | ||||
| -rw-r--r-- | sanei/sanei_init_debug.c | 34 | ||||
| -rw-r--r-- | sanei/sanei_lm983x.c | 14 | ||||
| -rw-r--r-- | sanei/sanei_magic.c | 103 | ||||
| -rw-r--r-- | sanei/sanei_pa4s2.c | 22 | ||||
| -rw-r--r-- | sanei/sanei_pio.c | 46 | ||||
| -rw-r--r-- | sanei/sanei_pp.c | 70 | ||||
| -rw-r--r-- | sanei/sanei_pv8630.c | 2 | ||||
| -rw-r--r-- | sanei/sanei_scsi.c | 96 | ||||
| -rw-r--r-- | sanei/sanei_thread.c | 25 | ||||
| -rw-r--r-- | sanei/sanei_udp.c | 1 | ||||
| -rw-r--r-- | sanei/sanei_usb.c | 2247 | ||||
| -rw-r--r-- | sanei/sanei_wire.c | 28 | 
21 files changed, 2185 insertions, 1248 deletions
| diff --git a/sanei/Makefile.am b/sanei/Makefile.am index a197343..46d3ff4 100644 --- a/sanei/Makefile.am +++ b/sanei/Makefile.am @@ -5,7 +5,7 @@  ##  included LICENSE file for license information.  AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include \ - -I$(top_srcdir)/include $(USB_CFLAGS) + -I$(top_srcdir)/include $(USB_CFLAGS) $(XML_CFLAGS)  noinst_LTLIBRARIES = libsanei.la diff --git a/sanei/Makefile.in b/sanei/Makefile.in deleted file mode 100644 index c6fa654..0000000 --- a/sanei/Makefile.in +++ /dev/null @@ -1,704 +0,0 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ -  case $${target_option-} in \ -      ?) ;; \ -      *) echo "am__make_running_with_option: internal error: invalid" \ -              "target option '$${target_option-}' specified" >&2; \ -         exit 1;; \ -  esac; \ -  has_opt=no; \ -  sane_makeflags=$$MAKEFLAGS; \ -  if $(am__is_gnu_make); then \ -    sane_makeflags=$$MFLAGS; \ -  else \ -    case $$MAKEFLAGS in \ -      *\\[\ \	]*) \ -        bs=\\; \ -        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ -          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \ -    esac; \ -  fi; \ -  skip_next=no; \ -  strip_trailopt () \ -  { \ -    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ -  }; \ -  for flg in $$sane_makeflags; do \ -    test $$skip_next = yes && { skip_next=no; continue; }; \ -    case $$flg in \ -      *=*|--*) continue;; \ -        -*I) strip_trailopt 'I'; skip_next=yes;; \ -      -*I?*) strip_trailopt 'I';; \ -        -*O) strip_trailopt 'O'; skip_next=yes;; \ -      -*O?*) strip_trailopt 'O';; \ -        -*l) strip_trailopt 'l'; skip_next=yes;; \ -      -*l?*) strip_trailopt 'l';; \ -      -[dEDm]) skip_next=yes;; \ -      -[JT]) skip_next=yes;; \ -    esac; \ -    case $$flg in \ -      *$$target_option*) has_opt=yes; break;; \ -    esac; \ -  done; \ -  test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -@HAVE_JPEG_TRUE@am__append_1 = sanei_jpeg.c -subdir = sanei -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ -	$(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ -	$(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ -	$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ -	$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/ltoptions.m4 \ -	$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ -	$(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ -	$(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ -	$(top_srcdir)/acinclude.m4 $(top_srcdir)/m4/libtool.m4 \ -	$(top_srcdir)/m4/byteorder.m4 $(top_srcdir)/m4/stdint.m4 \ -	$(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ -	$(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/include/sane/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libsanei_la_LIBADD = -am__libsanei_la_SOURCES_DIST = sanei_ab306.c sanei_constrain_value.c \ -	sanei_init_debug.c sanei_net.c sanei_wire.c \ -	sanei_codec_ascii.c sanei_codec_bin.c sanei_scsi.c \ -	sanei_config.c sanei_config2.c sanei_pio.c sanei_pa4s2.c \ -	sanei_auth.c sanei_usb.c sanei_thread.c sanei_pv8630.c \ -	sanei_pp.c sanei_lm983x.c sanei_access.c sanei_tcp.c \ -	sanei_udp.c sanei_magic.c sanei_ir.c sanei_jpeg.c -@HAVE_JPEG_TRUE@am__objects_1 = sanei_jpeg.lo -am_libsanei_la_OBJECTS = sanei_ab306.lo sanei_constrain_value.lo \ -	sanei_init_debug.lo sanei_net.lo sanei_wire.lo \ -	sanei_codec_ascii.lo sanei_codec_bin.lo sanei_scsi.lo \ -	sanei_config.lo sanei_config2.lo sanei_pio.lo sanei_pa4s2.lo \ -	sanei_auth.lo sanei_usb.lo sanei_thread.lo sanei_pv8630.lo \ -	sanei_pp.lo sanei_lm983x.lo sanei_access.lo sanei_tcp.lo \ -	sanei_udp.lo sanei_magic.lo sanei_ir.lo $(am__objects_1) -libsanei_la_OBJECTS = $(am_libsanei_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 =  -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo "  GEN     " $@; -am__v_GEN_1 =  -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 =  -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include/sane -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ -	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ -	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ -	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ -	$(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo "  CC      " $@; -am__v_CC_1 =  -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ -	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ -	$(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo "  CCLD    " $@; -am__v_CCLD_1 =  -SOURCES = $(libsanei_la_SOURCES) -DIST_SOURCES = $(am__libsanei_la_SOURCES_DIST) -am__can_run_installinfo = \ -  case $$AM_UPDATE_INFO_DIR in \ -    n|no|NO) false;; \ -    *) (install-info --version) >/dev/null 2>&1;; \ -  esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates.  Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ -  BEGIN { nonempty = 0; } \ -  { items[$$0] = 1; nonempty = 1; } \ -  END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique.  This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ -  list='$(am__tagged_files)'; \ -  unique=`for i in $$list; do \ -    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ -  done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALLOCA = @ALLOCA@ -AMTAR = @AMTAR@ -AM_CFLAGS = @AM_CFLAGS@ -AM_CPPFLAGS = @AM_CPPFLAGS@ -I. -I$(srcdir) -I$(top_builddir)/include \ -	-I$(top_srcdir)/include $(USB_CFLAGS) -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -AM_LDFLAGS = @AM_LDFLAGS@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AVAHI_CFLAGS = @AVAHI_CFLAGS@ -AVAHI_LIBS = @AVAHI_LIBS@ -AWK = @AWK@ -BACKENDS = @BACKENDS@ -BACKEND_CONFS_ENABLED = @BACKEND_CONFS_ENABLED@ -BACKEND_LIBS_ENABLED = @BACKEND_LIBS_ENABLED@ -BACKEND_MANS_ENABLED = @BACKEND_MANS_ENABLED@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DLH = @DLH@ -DLLTOOL = @DLLTOOL@ -DL_LIBS = @DL_LIBS@ -DSYMUTIL = @DSYMUTIL@ -DUMPBIN = @DUMPBIN@ -DVIPS = @DVIPS@ -DYNAMIC_FLAG = @DYNAMIC_FLAG@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -FIG2DEV = @FIG2DEV@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GPHOTO2_CPPFLAGS = @GPHOTO2_CPPFLAGS@ -GPHOTO2_LDFLAGS = @GPHOTO2_LDFLAGS@ -GPHOTO2_LIBS = @GPHOTO2_LIBS@ -GREP = @GREP@ -GS = @GS@ -HAVE_GPHOTO2 = @HAVE_GPHOTO2@ -IEEE1284_LIBS = @IEEE1284_LIBS@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_LOCKPATH = @INSTALL_LOCKPATH@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTLLIBS = @INTLLIBS@ -INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ -JPEG_LIBS = @JPEG_LIBS@ -LATEX = @LATEX@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBICONV = @LIBICONV@ -LIBINTL = @LIBINTL@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIBV4L_CFLAGS = @LIBV4L_CFLAGS@ -LIBV4L_LIBS = @LIBV4L_LIBS@ -LIPO = @LIPO@ -LN_S = @LN_S@ -LOCKPATH_GROUP = @LOCKPATH_GROUP@ -LTALLOCA = @LTALLOCA@ -LTLIBICONV = @LTLIBICONV@ -LTLIBINTL = @LTLIBINTL@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINDEX = @MAKEINDEX@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MATH_LIB = @MATH_LIB@ -MKDIR_P = @MKDIR_P@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PDFLATEX = @PDFLATEX@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -PNG_LIBS = @PNG_LIBS@ -POSUB = @POSUB@ -PPMTOGIF = @PPMTOGIF@ -PRELOADABLE_BACKENDS = @PRELOADABLE_BACKENDS@ -PRELOADABLE_BACKENDS_ENABLED = @PRELOADABLE_BACKENDS_ENABLED@ -PTHREAD_LIBS = @PTHREAD_LIBS@ -RANLIB = @RANLIB@ -RESMGR_LIBS = @RESMGR_LIBS@ -SANEI_SANEI_JPEG_LO = @SANEI_SANEI_JPEG_LO@ -SANE_CONFIG_PATH = @SANE_CONFIG_PATH@ -SCSI_LIBS = @SCSI_LIBS@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -SNMP_CFLAGS = @SNMP_CFLAGS@ -SNMP_CONFIG_PATH = @SNMP_CONFIG_PATH@ -SNMP_LIBS = @SNMP_LIBS@ -SOCKET_LIBS = @SOCKET_LIBS@ -STRICT_LDFLAGS = @STRICT_LDFLAGS@ -STRIP = @STRIP@ -SYSLOG_LIBS = @SYSLOG_LIBS@ -SYSTEMD_CFLAGS = @SYSTEMD_CFLAGS@ -SYSTEMD_LIBS = @SYSTEMD_LIBS@ -TIFF_LIBS = @TIFF_LIBS@ -USB_CFLAGS = @USB_CFLAGS@ -USB_LIBS = @USB_LIBS@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -V_MAJOR = @V_MAJOR@ -V_MINOR = @V_MINOR@ -V_REV = @V_REV@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -configdir = @configdir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -effective_target = @effective_target@ -exec_prefix = @exec_prefix@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -locksanedir = @locksanedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -noinst_LTLIBRARIES = libsanei.la -libsanei_la_SOURCES = sanei_ab306.c sanei_constrain_value.c \ -	sanei_init_debug.c sanei_net.c sanei_wire.c \ -	sanei_codec_ascii.c sanei_codec_bin.c sanei_scsi.c \ -	sanei_config.c sanei_config2.c sanei_pio.c sanei_pa4s2.c \ -	sanei_auth.c sanei_usb.c sanei_thread.c sanei_pv8630.c \ -	sanei_pp.c sanei_lm983x.c sanei_access.c sanei_tcp.c \ -	sanei_udp.c sanei_magic.c sanei_ir.c $(am__append_1) -EXTRA_DIST = linux_sg3_err.h os2_srb.h sanei_DomainOS.c sanei_DomainOS.h -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps) -	@for dep in $?; do \ -	  case '$(am__configure_deps)' in \ -	    *$$dep*) \ -	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ -	        && { if test -f $@; then exit 0; else break; fi; }; \ -	      exit 1;; \ -	  esac; \ -	done; \ -	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu sanei/Makefile'; \ -	$(am__cd) $(top_srcdir) && \ -	  $(AUTOMAKE) --gnu sanei/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status -	@case '$?' in \ -	  *config.status*) \ -	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ -	  *) \ -	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ -	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ -	esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) -	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) -	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) -	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -clean-noinstLTLIBRARIES: -	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) -	@list='$(noinst_LTLIBRARIES)'; \ -	locs=`for p in $$list; do echo $$p; done | \ -	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ -	      sort -u`; \ -	test -z "$$locs" || { \ -	  echo rm -f $${locs}; \ -	  rm -f $${locs}; \ -	} - -libsanei.la: $(libsanei_la_OBJECTS) $(libsanei_la_DEPENDENCIES) $(EXTRA_libsanei_la_DEPENDENCIES)  -	$(AM_V_CCLD)$(LINK)  $(libsanei_la_OBJECTS) $(libsanei_la_LIBADD) $(LIBS) - -mostlyclean-compile: -	-rm -f *.$(OBJEXT) - -distclean-compile: -	-rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_ab306.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_access.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_auth.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_codec_ascii.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_codec_bin.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_config2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_constrain_value.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_init_debug.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_ir.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_jpeg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_lm983x.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_magic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_net.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_pa4s2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_pio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_pp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_pv8630.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_scsi.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_tcp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_thread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_udp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_usb.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanei_wire.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@	$(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@	$(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: -	-rm -f *.lo - -clean-libtool: -	-rm -rf .libs _libs - -ID: $(am__tagged_files) -	$(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) -	set x; \ -	here=`pwd`; \ -	$(am__define_uniq_tagged_files); \ -	shift; \ -	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ -	  test -n "$$unique" || unique=$$empty_fix; \ -	  if test $$# -gt 0; then \ -	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -	      "$$@" $$unique; \ -	  else \ -	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ -	      $$unique; \ -	  fi; \ -	fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) -	$(am__define_uniq_tagged_files); \ -	test -z "$(CTAGS_ARGS)$$unique" \ -	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ -	     $$unique - -GTAGS: -	here=`$(am__cd) $(top_builddir) && pwd` \ -	  && $(am__cd) $(top_srcdir) \ -	  && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) -	list='$(am__tagged_files)'; \ -	case "$(srcdir)" in \ -	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ -	  *) sdir=$(subdir)/$(srcdir) ;; \ -	esac; \ -	for i in $$list; do \ -	  if test -f "$$i"; then \ -	    echo "$(subdir)/$$i"; \ -	  else \ -	    echo "$$sdir/$$i"; \ -	  fi; \ -	done >> $(top_builddir)/cscope.files - -distclean-tags: -	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) -	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ -	list='$(DISTFILES)'; \ -	  dist_files=`for file in $$list; do echo $$file; done | \ -	  sed -e "s|^$$srcdirstrip/||;t" \ -	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ -	case $$dist_files in \ -	  */*) $(MKDIR_P) `echo "$$dist_files" | \ -			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ -			   sort -u` ;; \ -	esac; \ -	for file in $$dist_files; do \ -	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ -	  if test -d $$d/$$file; then \ -	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ -	    if test -d "$(distdir)/$$file"; then \ -	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -	    fi; \ -	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ -	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ -	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ -	    fi; \ -	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ -	  else \ -	    test -f "$(distdir)/$$file" \ -	    || cp -p $$d/$$file "$(distdir)/$$file" \ -	    || exit 1; \ -	  fi; \ -	done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) -installdirs: -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am -	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: -	if test -z '$(STRIP)'; then \ -	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ -	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ -	      install; \ -	else \ -	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ -	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ -	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ -	fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: -	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: -	@echo "This command is intended for maintainers to use" -	@echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ -	mostlyclean-am - -distclean: distclean-am -	-rm -rf ./$(DEPDIR) -	-rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ -	distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am -	-rm -rf ./$(DEPDIR) -	-rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ -	mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ -	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ -	ctags-am distclean distclean-compile distclean-generic \ -	distclean-libtool distclean-tags distdir dvi dvi-am html \ -	html-am info info-am install install-am install-data \ -	install-data-am install-dvi install-dvi-am install-exec \ -	install-exec-am install-html install-html-am install-info \ -	install-info-am install-man install-pdf install-pdf-am \ -	install-ps install-ps-am install-strip installcheck \ -	installcheck-am installdirs maintainer-clean \ -	maintainer-clean-generic mostlyclean mostlyclean-compile \ -	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ -	tags tags-am uninstall uninstall-am - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/sanei/sanei_DomainOS.c b/sanei/sanei_DomainOS.c index 5473151..7b851a8 100644 --- a/sanei/sanei_DomainOS.c +++ b/sanei/sanei_DomainOS.c @@ -326,7 +326,7 @@ static void DomainSCSIWait(void)                       static status_$t sense_status;                       static pinteger sense_return_count;                       static int temp; -             +                       /* Issue the sense command (wire, issue, wait, unwire */                       sense_cdb_size = sizeof(scanner_sense_cdb);                       memcpy(&sense_cdb, scanner_sense_cdb, sense_cdb_size); diff --git a/sanei/sanei_DomainOS.h b/sanei/sanei_DomainOS.h index ff93503..8f88e5f 100644 --- a/sanei/sanei_DomainOS.h +++ b/sanei/sanei_DomainOS.h @@ -73,4 +73,3 @@ struct DomainServerCommon     };  #endif /*DomainSenseSize*/ - diff --git a/sanei/sanei_ab306.c b/sanei/sanei_ab306.c index 898acf6..4483fec 100644 --- a/sanei/sanei_ab306.c +++ b/sanei/sanei_ab306.c @@ -294,7 +294,7 @@ sanei_ab306_open (const char *dev, int *fdp)    status = sanei_ab306_get_io_privilege (i);    if (status != SANE_STATUS_GOOD)      return status; -   +    DBG(1, "sanei_ab306_ioport: using inb/outb access\n");    for (j = 0; j < NELEMS(wakeup); ++j)      { @@ -477,7 +477,7 @@ sanei_ab306_rdata (int fd, int planes, SANE_Byte * buf, int lines, int bpl)  	  do  	    nstat = ab306_inb (p, p->base + 1);  	  while (((p->lstat ^ nstat) & 0x10) == 0); -	   +  	  if (p->port_fd >= 0)  	    {  	      /* the pixel-loop: */ diff --git a/sanei/sanei_access.c b/sanei/sanei_access.c index b77cdd9..cb19c5c 100644 --- a/sanei/sanei_access.c +++ b/sanei/sanei_access.c @@ -80,10 +80,10 @@  #ifdef ENABLE_LOCKING  /** get the status/owner of a lock file   * - * The function tries to open an existing lockfile. On success, it reads out  + * The function tries to open an existing lockfile. On success, it reads out   * the pid which is stored inside and tries to find out more about the status   * of the process with the corresponding PID. - *  + *   * @param fn - the complete filename of the lockfile to check   * @return   * - PROCESS_SELF  - the calling process is owner of the lockfile @@ -96,10 +96,10 @@ get_lock_status( char *fn )  	char  pid_buf[PID_BUFSIZE];  	int   fd, status;  	pid_t pid; -	 +  	fd = open( fn, O_RDONLY );  	if( fd < 0 ) { -		DBG( 2, "does_process_exist: open >%s< failed: %s\n",  +		DBG( 2, "does_process_exist: open >%s< failed: %s\n",  		        fn, strerror(errno));  		return PROCESS_OTHER;  	} @@ -155,7 +155,7 @@ sanei_access_init( const char *backend )  	DBG( 2, "sanei_access_init: >%s<\n", backend);  } -SANE_Status  +SANE_Status  sanei_access_lock( const char *devicename, SANE_Word timeout )  {  #ifdef ENABLE_LOCKING @@ -164,7 +164,7 @@ sanei_access_lock( const char *devicename, SANE_Word timeout )  	int  fd, to, i;  #endif -	DBG( 2, "sanei_access_lock: devname >%s<, timeout: %u\n",  +	DBG( 2, "sanei_access_lock: devname >%s<, timeout: %u\n",  	        devicename, timeout );  #ifndef ENABLE_LOCKING  	return SANE_STATUS_GOOD; @@ -179,7 +179,7 @@ sanei_access_lock( const char *devicename, SANE_Word timeout )  		fd = open( fn, O_CREAT | O_EXCL | O_WRONLY, 0644 );  		if (fd < 0) { -	 +  			if (errno == EEXIST) {  				switch( get_lock_status( fn )) {  				case PROCESS_DEAD: @@ -198,7 +198,7 @@ sanei_access_lock( const char *devicename, SANE_Word timeout )  				DBG( 2, "sanei_access_lock: lock exists, waiting...\n" );  				sleep(1);  			} else { -				DBG( 1, "sanei_access_lock: open >%s< failed: %s\n",  +				DBG( 1, "sanei_access_lock: open >%s< failed: %s\n",  				        fn, strerror(errno));  				return SANE_STATUS_ACCESS_DENIED;  			} @@ -215,7 +215,7 @@ sanei_access_lock( const char *devicename, SANE_Word timeout )  #endif  } -SANE_Status  +SANE_Status  sanei_access_unlock( const char *devicename )  {  #ifdef ENABLE_LOCKING diff --git a/sanei/sanei_auth.c b/sanei/sanei_auth.c index cbba06c..9039187 100644 --- a/sanei/sanei_auth.c +++ b/sanei/sanei_auth.c @@ -36,7 +36,7 @@     If you write modifications of your own for SANE, it is your choice     whether to permit this exception to apply to your modifications. -   If you do not wish that, delete this exception notice.  +   If you do not wish that, delete this exception notice.     This file implements an interface for user authorization using MD5 digest */ diff --git a/sanei/sanei_config.c b/sanei/sanei_config.c index c158766..0eaee9a 100644 --- a/sanei/sanei_config.c +++ b/sanei/sanei_config.c @@ -227,7 +227,7 @@ sanei_config_read (char *str, int n, FILE *stream)     while( isspace( *start))        start++; -   if (start != str)  +   if (start != str)        do {           *str++ = *start++;        } while( *str); @@ -266,7 +266,7 @@ sanei_configure_attach (const char *config_file, SANEI_Config * config,      }    /* loop reading the configuration file, all line beginning by "option " are -   * parsed for value to store in configuration structure, other line are  +   * parsed for value to store in configuration structure, other line are     * used are device to try to attach     */    while (sanei_config_read (line, PATH_MAX, fp) && status == SANE_STATUS_GOOD) @@ -292,7 +292,7 @@ sanei_configure_attach (const char *config_file, SANEI_Config * config,        /* to ensure maximum compatibility, we accept line like:         * option "option_name" "option_value" -       * "option_name" "option_value"  +       * "option_name" "option_value"         * So we parse the line 2 time to find an option */        /* check if it is an option */        lp = sanei_config_get_string (lp, &token); @@ -405,7 +405,7 @@ sanei_configure_attach (const char *config_file, SANEI_Config * config,  		       config->descriptors[i]->type,  		       config->descriptors[i]->name);  		} -	       +  	      /* check decoded value */  	      status = sanei_check_value (config->descriptors[i], value); @@ -438,7 +438,7 @@ sanei_configure_attach (const char *config_file, SANEI_Config * config,  	  /* to avoid every backend to depend on scsi and usb functions  	   * we call back the backend for attach. In turn it will call  	   * sanei_usb_attach_matching_devices, sanei_config_attach_matching_devices -	   * or other. This means 2 callback functions per backend using this  +	   * or other. This means 2 callback functions per backend using this  	   * function. */  	  DBG (3, "sanei_configure_attach: trying to attach with '%s'\n",  	       lp2); diff --git a/sanei/sanei_config2.c b/sanei/sanei_config2.c index 44c6b93..cd9484d 100644 --- a/sanei/sanei_config2.c +++ b/sanei/sanei_config2.c @@ -149,6 +149,6 @@ sanei_config_attach_matching_devices (const char *name,        if (type)  	free (type);      } -  else  +  else      (*attach) (name);  } diff --git a/sanei/sanei_init_debug.c b/sanei/sanei_init_debug.c index 0abb891..3cde74e 100644 --- a/sanei/sanei_init_debug.c +++ b/sanei/sanei_init_debug.c @@ -58,6 +58,8 @@  #include <sys/socket.h>  #endif  #include <sys/stat.h> +#include <time.h> +#include <sys/time.h>  #ifdef HAVE_OS2_H  # define INCL_DOS @@ -107,16 +109,31 @@ sanei_init_debug (const char * backend, int * var)    DBG (0, "Setting debug level of %s to %d.\n", backend, *var);  } +static int +is_socket (int fd) +{ +  struct stat sbuf; + +  if (fstat(fd, &sbuf) == -1) return 0; + +#if defined(S_ISSOCK) +  return S_ISSOCK(sbuf.st_mode); +#elif defined (S_IFMT) && defined(S_IFMT) +  return (sbuf.st_mode & S_IFMT) == S_IFSOCK; +#else +  return 0; +#endif +} +  void  sanei_debug_msg    (int level, int max_level, const char *be, const char *fmt, va_list ap)  {    char *msg; -	 +    if (max_level >= level)      { -#ifdef S_IFSOCK -      if ( 1 == isfdtype(fileno(stderr), S_IFSOCK) ) +      if (is_socket(fileno(stderr)))  	{  	  msg = (char *)malloc (sizeof(char) * (strlen(be) + strlen(fmt) + 4));  	  if (msg == NULL) @@ -132,12 +149,17 @@ sanei_debug_msg  	    }  	}        else -#endif  	{ -	  fprintf (stderr, "[%s] ", be); +          struct timeval tv; +          struct tm *t; + +          gettimeofday (&tv, NULL); +          t = localtime (&tv.tv_sec); + +          fprintf (stderr, "[%02d:%02d:%02d.%06ld] [%s] ", t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec, be);            vfprintf (stderr, fmt, ap);  	} -	  +      }  } diff --git a/sanei/sanei_lm983x.c b/sanei/sanei_lm983x.c index 5b41985..62dfad9 100644 --- a/sanei/sanei_lm983x.c +++ b/sanei/sanei_lm983x.c @@ -4,7 +4,7 @@     Copyright (C) 2002-2004 Gerhard Jaeger <gerhard@gjaeger.de>     This file is part of the SANE package. -  +     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License as     published by the Free Software Foundation; either version 2 of the @@ -96,20 +96,20 @@ sanei_lm983x_write( SANE_Int fd, SANE_Byte reg,  	DBG( 15, "sanei_lm983x_write: fd=%d, reg=%d, len=%d, increment=%d\n", fd,  	         reg, len, increment); -	 +  	if( reg > _LM9831_MAX_REG ) {  		DBG( 1, "sanei_lm983x_write: register out of range (%u>%u)\n",  				 reg, _LM9831_MAX_REG );  		return SANE_STATUS_INVAL;  	} -	 +  	for( bytes = 0; len > 0; ) {  		max_len = _MIN( len, _MAX_TRANSFER_SIZE );  		command_buffer[0] = 0;                      /* write              */  		command_buffer[1] = reg;                    /* LM983x register    */ -		 +  		if( increment == SANE_TRUE ) {  			command_buffer[0] += 0x02;              /* increase reg?      */  			command_buffer[1] += bytes; @@ -122,7 +122,7 @@ sanei_lm983x_write( SANE_Int fd, SANE_Byte reg,  		size   = (max_len + _CMD_BYTE_CNT);  		result = sanei_usb_write_bulk( fd, command_buffer, &size ); -		 +  		if( SANE_STATUS_GOOD != result )  			return result; @@ -183,7 +183,7 @@ sanei_lm983x_read( SANE_Int fd, SANE_Byte reg,  		if( SANE_STATUS_GOOD != result )  			return result; -		 +  		if( size != _CMD_BYTE_CNT) {  			DBG( 1, "sanei_lm983x_read: short write while writing command "  			        "(%d/_CMD_BYTE_CNT)\n", result); @@ -228,7 +228,7 @@ SANE_Bool sanei_lm983x_reset( SANE_Int fd )  	DBG( 15, "sanei_lm983x_reset()\n" );  	for( i = 0; i < _MAX_RETRY; i++ ) { -		 +  		/* Read the command register and check that the reset bit is not set  		 * If it is set, clear it and return false to indicate that  		 * the bit has only now been cleared diff --git a/sanei/sanei_magic.c b/sanei/sanei_magic.c index bfd56cc..3e71946 100644 --- a/sanei/sanei_magic.c +++ b/sanei/sanei_magic.c @@ -123,17 +123,17 @@ sanei_magic_despeck (SANE_Parameters * params, SANE_Byte * buffer,          /* convert darkest pixel into a brighter threshold */          thresh = (thresh + 255*3 + 255*3)/3; -   +          /*loop over rows and columns around window */          for(k=-1; k<diam+1; k++){            for(l=-1; l<diam+1; l++){              int tmp[3]; -   +              /* dont count pixels in the window */              if(k != -1 && k != diam && l != -1 && l != diam)                continue; -   +              for(n=0; n<3; n++){                tmp[n] = buffer[i + j*3 + k*bw + l*3 + n];                outer[n] += tmp[n]; @@ -182,7 +182,7 @@ sanei_magic_despeck (SANE_Parameters * params, SANE_Byte * buffer,          /* convert darkest pixel into a brighter threshold */          thresh = (thresh + 255 + 255)/3; -   +          /*loop over rows and columns around window */          for(k=-1; k<diam+1; k++){            for(l=-1; l<diam+1; l++){ @@ -192,7 +192,7 @@ sanei_magic_despeck (SANE_Parameters * params, SANE_Byte * buffer,              /* dont count pixels in the window */              if(k != -1 && k != diam && l != -1 && l != diam)                continue; -   +              tmp = buffer[i + j + k*bw + l];              if(tmp < thresh){ @@ -222,7 +222,7 @@ sanei_magic_despeck (SANE_Parameters * params, SANE_Byte * buffer,    else if(params->format == SANE_FRAME_GRAY && params->depth == 1){      for(i=bw; i<bt-bw-(bw*diam); i+=bw){        for(j=1; j<pw-1-diam; j++){ -         +          int curr = 0;          int hits = 0; @@ -242,7 +242,7 @@ sanei_magic_despeck (SANE_Parameters * params, SANE_Byte * buffer,              /* dont count pixels in the window */              if(k != -1 && k != diam && l != -1 && l != diam)                continue; -   +              hits += buffer[i + k*bw + (j+l)/8] >> (7-(j+l)%8) & 1;              if(hits) @@ -631,7 +631,7 @@ sanei_magic_rotate (SANE_Parameters * params, SANE_Byte * buffer,      goto cleanup;    } -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -642,19 +642,19 @@ sanei_magic_rotate (SANE_Parameters * params, SANE_Byte * buffer,      for (i=0; i<height; i++) {        int shiftY = centerY - i; -     +        for (j=0; j<pwidth; j++) {          int shiftX = centerX - j;          int sourceX, sourceY; -     +          sourceX = centerX - (int)(shiftX * slopeCos + shiftY * slopeSin);          if (sourceX < 0 || sourceX >= pwidth)            continue; -     +          sourceY = centerY + (int)(-shiftY * slopeCos + shiftX * slopeSin);          if (sourceY < 0 || sourceY >= height)            continue; -     +          for (k=0; k<depth; k++) {            outbuf[i*bwidth+j*depth+k]              = buffer[sourceY*bwidth+sourceX*depth+k]; @@ -672,15 +672,15 @@ sanei_magic_rotate (SANE_Parameters * params, SANE_Byte * buffer,      for (i=0; i<height; i++) {        int shiftY = centerY - i; -     +        for (j=0; j<pwidth; j++) {          int shiftX = centerX - j;          int sourceX, sourceY; -     +          sourceX = centerX - (int)(shiftX * slopeCos + shiftY * slopeSin);          if (sourceX < 0 || sourceX >= pwidth)            continue; -     +          sourceY = centerY + (int)(-shiftY * slopeCos + shiftX * slopeSin);          if (sourceY < 0 || sourceY >= height)            continue; @@ -689,7 +689,7 @@ sanei_magic_rotate (SANE_Parameters * params, SANE_Byte * buffer,          outbuf[i*bwidth + j/8] &= ~(1 << (7-(j%8)));          /* fill in new bit */ -        outbuf[i*bwidth + j/8] |=  +        outbuf[i*bwidth + j/8] |=            ((buffer[sourceY*bwidth + sourceX/8]            >> (7-(sourceX%8))) & 1) << (7-(j%8));        } @@ -726,7 +726,7 @@ sanei_magic_isBlank (SANE_Parameters * params, SANE_Byte * buffer,    /*convert thresh from percent (0-100) to 0-1 range*/    thresh /= 100; -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -783,7 +783,7 @@ sanei_magic_isBlank (SANE_Parameters * params, SANE_Byte * buffer,  /* Divide the image into 1/2 inch squares, skipping a 1/4 inch   * margin on all sides. If all squares are under the user's density, - * signal our caller to skip the image entirely, by returning  + * signal our caller to skip the image entirely, by returning   * SANE_STATUS_NO_DOCS */  SANE_Status  sanei_magic_isBlank2 (SANE_Parameters * params, SANE_Byte * buffer, @@ -813,12 +813,12 @@ sanei_magic_isBlank2 (SANE_Parameters * params, SANE_Byte * buffer,      for(yb=0; yb<yblocks; yb++){        for(xb=0; xb<xblocks; xb++){ -   +          /*count dark pix in this block*/          double blocksum = 0; -   +          for(y=0; y<yhalf; y++){ -   +            /* skip the top and left 1/4 inch */            int offset = (yquarter + yb*yhalf + y) * params->bytes_per_line              + (xquarter + xb*xhalf) * Bpp; @@ -826,7 +826,7 @@ sanei_magic_isBlank2 (SANE_Parameters * params, SANE_Byte * buffer,            /*count darkness of pix in this row*/            int rowsum = 0; -   +            for(x=0; x<xhalf*Bpp; x++){              rowsum += 255 - ptr[x];            } @@ -847,12 +847,12 @@ sanei_magic_isBlank2 (SANE_Parameters * params, SANE_Byte * buffer,      for(yb=0; yb<yblocks; yb++){        for(xb=0; xb<xblocks; xb++){ -   +          /*count dark pix in this block*/          double blocksum = 0; -   +          for(y=0; y<yhalf; y++){ -   +            /* skip the top and left 1/4 inch */            int offset = (yquarter + yb*yhalf + y) * params->bytes_per_line              + (xquarter + xb*xhalf) / 8; @@ -860,7 +860,7 @@ sanei_magic_isBlank2 (SANE_Parameters * params, SANE_Byte * buffer,            /*count darkness of pix in this row*/            int rowsum = 0; -   +            for(x=0; x<xhalf; x++){              rowsum += ptr[x/8] >> (7-(x%8)) & 1;            } @@ -898,7 +898,7 @@ sanei_magic_findTurn(SANE_Parameters * params, SANE_Byte * buffer,    DBG(10,"sanei_magic_findTurn: start\n"); -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -1125,7 +1125,7 @@ sanei_magic_turn(SANE_Parameters * params, SANE_Byte * buffer,    }    /*turn color & gray image*/ -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -1282,7 +1282,7 @@ getTopEdge(int width, int height, int resolution,    double topSlope = 0;    int topOffset = 0;    int topDensity = 0; -   +    int i,j;    int pass = 0; @@ -1436,7 +1436,7 @@ getLine (int height, int width, int * buff,      /* find central value of this 'bucket' */      slopeCenter[j] = ( -      (double)j*(maxSlope-minSlope)/slopes+minSlope  +      (double)j*(maxSlope-minSlope)/slopes+minSlope        + (double)(j+1)*(maxSlope-minSlope)/slopes+minSlope      )/2; @@ -1525,7 +1525,7 @@ getLine (int height, int width, int * buff,          maxDensity = lines[i][j];      }    } -   +    DBG(15,"getLine: maxDensity %d\n",maxDensity);    *finSlope = 0; @@ -1544,20 +1544,20 @@ getLine (int height, int width, int * buff,        }      }    } -   +    if(0){      fprintf(stderr,"offsetCenter:       ");      for(j=0;j<offsets;j++){        fprintf(stderr," %+04.0f",offsetCenter[j]);      }      fprintf(stderr,"\n"); -   +      fprintf(stderr,"offsetScale:        ");      for(j=0;j<offsets;j++){        fprintf(stderr," %04d",offsetScale[j]);      }      fprintf(stderr,"\n"); -   +      for(i=0;i<slopes;i++){        fprintf(stderr,"slope: %02d %+02.2f %03d:",i,slopeCenter[i],slopeScale[i]);        for(j=0;j<offsets;j++){ @@ -1589,12 +1589,12 @@ getLine (int height, int width, int * buff,    return ret;  } -/* find the left side of paper by moving a line  +/* find the left side of paper by moving a line   * perpendicular to top slope across the image   * the 'left-most' point on the paper is the   * one with the smallest X intercept   * return x and y intercepts */ -static SANE_Status  +static SANE_Status  getLeftEdge (int width, int height, int * top, int * bot,   double slope, int * finXInter, int * finYInter)  { @@ -1611,7 +1611,7 @@ getLeftEdge (int width, int height, int * top, int * bot,    leftCount = 0;    for(i=0;i<width;i++){ -     +      if(top[i] < height){        int tyi = top[i] - (slope * i);        int txi = tyi/-slope; @@ -1638,7 +1638,7 @@ getLeftEdge (int width, int height, int * top, int * bot,    leftCount = 0;    for(i=0;i<width;i++){ -     +      if(bot[i] > -1){        int byi = bot[i] - (slope * i); @@ -1677,7 +1677,7 @@ getLeftEdge (int width, int height, int * top, int * bot,  /* Loop thru the image and look for first color change in each column.   * Return a malloc'd array. Caller is responsible for freeing. */ -int *  +int *  sanei_magic_getTransY (    SANE_Parameters * params, int dpi, SANE_Byte * buffer, int top)  { @@ -1715,7 +1715,7 @@ sanei_magic_getTransY (    /* load the buff array with y value for first color change from edge     * gray/color uses a different algo from binary/halftone */ -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -1734,10 +1734,10 @@ sanei_magic_getTransY (        }        near *= winLen;        far = near; -   +        /* move windows, check delta */        for(j=firstLine+direction; j!=lastLine; j+=direction){ -   +          int farLine = j-winLen*2*direction;          int nearLine = j-winLen*direction; @@ -1770,10 +1770,10 @@ sanei_magic_getTransY (      int near = 0;      for(i=0; i<width; i++){ -   +        /* load the near window with first pixel */        near = buffer[(firstLine*width+i)/8] >> (7-(i%8)) & 1; -   +        /* move */        for(j=firstLine+direction; j!=lastLine; j+=direction){          if((buffer[(j*width+i)/8] >> (7-(i%8)) & 1) != near){ @@ -1809,7 +1809,7 @@ sanei_magic_getTransY (  /* Loop thru the image height and look for first color change in each row.   * Return a malloc'd array. Caller is responsible for freeing. */ -int *  +int *  sanei_magic_getTransX (    SANE_Parameters * params, int dpi, SANE_Byte * buffer, int left)  { @@ -1848,7 +1848,7 @@ sanei_magic_getTransX (    /* load the buff array with x value for first color change from edge     * gray/color uses a different algo from binary/halftone */ -  if(params->format == SANE_FRAME_RGB ||  +  if(params->format == SANE_FRAME_RGB ||      (params->format == SANE_FRAME_GRAY && params->depth == 8)    ){ @@ -1867,10 +1867,10 @@ sanei_magic_getTransX (        }        near *= winLen;        far = near; -   +        /* move windows, check delta */        for(j=firstCol+direction; j!=lastCol; j+=direction){ -   +          int farCol = j-winLen*2*direction;          int nearCol = j-winLen*direction; @@ -1888,7 +1888,7 @@ sanei_magic_getTransX (            near -= buffer[i*bwidth + nearCol*depth + k];            near += buffer[i*bwidth + j*depth + k];          } -   +          if(abs(near - far) > 50*winLen*depth - near*40/255){            buff[i] = j;            break; @@ -1902,10 +1902,10 @@ sanei_magic_getTransX (      int near = 0;      for(i=0; i<height; i++){ -   +        /* load the near window with first pixel */        near = buffer[i*bwidth + firstCol/8] >> (7-(firstCol%8)) & 1; -   +        /* move */        for(j=firstCol+direction; j!=lastCol; j+=direction){          if((buffer[i*bwidth + j/8] >> (7-(j%8)) & 1) != near){ @@ -1938,4 +1938,3 @@ sanei_magic_getTransX (    return buff;  } - diff --git a/sanei/sanei_pa4s2.c b/sanei/sanei_pa4s2.c index d1be0c0..282e6fd 100644 --- a/sanei/sanei_pa4s2.c +++ b/sanei/sanei_pa4s2.c @@ -37,7 +37,7 @@     If you write modifications of your own for SANE, it is your choice     whether to permit this exception to apply to your modifications. -   If you do not wish that, delete this exception notice.  +   If you do not wish that, delete this exception notice.     This file implements an interface for the Mustek PP chipset A4S2 */ @@ -48,7 +48,7 @@     3 - things nice to know     4 - code flow     5 - detailed flow -   6 - everything  +   6 - everything     These debug levels can be set using the environment variable     SANE_DEBUG_SANEI_PA4S2 */ @@ -333,7 +333,7 @@ pa4s2_init (SANE_Status *status)      }    DBG (3, "pa4s2_init: %d ports reported by IEEE 1284 library\n", pplist.portc); -   +    for (n=0; n<pplist.portc; n++)      DBG (6, "pa4s2_init: port %d is `%s`\n", n, pplist.portv[n]->name); @@ -388,7 +388,7 @@ pa4s2_open (const char *dev, SANE_Status * status)  #if !defined (HAVE_LIBIEEE1284)    u_long base;  #endif -   +    DBG (4, "pa4s2_open: trying to attach dev `%s`\n", dev);    if ((result = pa4s2_init(status)) != 0) @@ -397,7 +397,7 @@ pa4s2_open (const char *dev, SANE_Status * status)        DBG (1, "pa4s2_open: failed to initialize\n");        return result;      } -   +  #if !defined (HAVE_LIBIEEE1284)    { @@ -526,7 +526,7 @@ pa4s2_open (const char *dev, SANE_Status * status)    if (ioperm (port[n].base, 5, 1))      { -      DBG (1, "pa4s2_open: cannot get io privilege for port 0x%03lx\n",  +      DBG (1, "pa4s2_open: cannot get io privilege for port 0x%03lx\n",        		port[n].base); @@ -715,7 +715,7 @@ pa4s2_readbyte_nib (int fd)  {    u_char val; -   +    outbyte2 (fd, 0x05);    val = inbyte1(fd);    val >>= 4; @@ -891,7 +891,7 @@ pa4s2_close (int fd, SANE_Status * status)      {  #if defined(HAVE_LIBIEEE1284) -      DBG (1, "pa4s2_close: can't free port '%s' (%s)\n",  +      DBG (1, "pa4s2_close: can't free port '%s' (%s)\n",        		pplist.portv[fd]->name, pa4s2_libieee1284_errorstr(result));  #else        DBG (1, "pa4s2_close: can't free port 0x%03lx\n", port[fd].base); @@ -1034,7 +1034,7 @@ sanei_pa4s2_scsi_pp_get_status(int fd, u_char *status)  /*   * SCSI-over-parallel scanners need this done when a register is   * selected - */  + */  SANE_Status  sanei_pa4s2_scsi_pp_reg_select (int fd, int reg)  { @@ -1430,7 +1430,7 @@ sanei_pa4s2_enable (int fd, int enable)        /* io-permissions are not inherited after fork (at least not on           linux 2.2, although they seem to be inherited on linux 2.4),           so we should make sure we get the permission */ -       +        if (ioperm (port[fd].base, 5, 1))        {            DBG (1, "sanei_pa4s2_enable: cannot get io privilege for port" @@ -1457,7 +1457,7 @@ sanei_pa4s2_enable (int fd, int enable)      {  #if defined(HAVE_LIBIEEE1284) -      DBG (4, "sanei_pa4s2_enable: disable port '%s'\n",  +      DBG (4, "sanei_pa4s2_enable: disable port '%s'\n",        		pplist.portv[fd]->name);  #else        DBG (4, "sanei_pa4s2_enable: disable port 0x%03lx\n", port[fd].base); diff --git a/sanei/sanei_pio.c b/sanei/sanei_pio.c index 00e40ee..3290704 100644 --- a/sanei/sanei_pio.c +++ b/sanei/sanei_pio.c @@ -112,7 +112,7 @@ inb (u_long port)  #define PORT_DEV	"/dev/port"  /*    base    278 (lpt2) -    +                ioport  stat    ctrl        offs    0       1       2        len     1       1       1     */ @@ -174,7 +174,7 @@ static int pio_write (const Port port, const u_char * buf, int n);  static int pio_read (const Port port, u_char * buf, int n);  static int pio_open (const char *dev, SANE_Status * status); -static inline int  +static inline int  pio_outb (const Port port, u_char val, u_long addr)  { @@ -190,7 +190,7 @@ pio_outb (const Port port, u_char val, u_long addr)    return 0;  } -static inline int  +static inline int  pio_inb (const Port port, u_char * val, u_long addr)  { @@ -206,7 +206,7 @@ pio_inb (const Port port, u_char * val, u_long addr)    return 0;  } -static inline int  +static inline int  pio_wait (const Port port, u_char val, u_char mask)  {    int stat = 0; @@ -268,7 +268,7 @@ pio_ctrl (const Port port, u_char val)    return;  } -static inline void  +static inline void  pio_delay (const Port port)  {    inb (port->base + PIO_STAT);	/* delay */ @@ -276,14 +276,14 @@ pio_delay (const Port port)    return;  } -static inline void  +static inline void  pio_init (const Port port)  {    pio_ctrl (port, PIO_CTRL_IE);    return;  } -static void  +static void  pio_reset (const Port port)  {    int n; @@ -302,7 +302,7 @@ pio_reset (const Port port)    return;  } -static int  +static int  pio_write (const Port port, const u_char * buf, int n)  {    int k; @@ -356,7 +356,7 @@ pio_write (const Port port, const u_char * buf, int n)    return k;  } -static int  +static int  pio_read (const Port port, u_char * buf, int n)  {    int k; @@ -401,10 +401,10 @@ pio_read (const Port port, u_char * buf, int n)  }  /* -     Open the device, <dev> must contain a valid port number (as string).    +     Open the device, <dev> must contain a valid port number (as string).   */ -static int  +static int  pio_open (const char *dev, SANE_Status * status)  {    static int first_time = 1; @@ -481,7 +481,7 @@ pio_open (const char *dev, SANE_Status * status)    return n;  } -SANE_Status  +SANE_Status  sanei_pio_open (const char *dev, int *fdp)  {    SANE_Status status; @@ -490,7 +490,7 @@ sanei_pio_open (const char *dev, int *fdp)    return status;  } -void  +void  sanei_pio_close (int fd)  {    Port p = port + fd; @@ -512,7 +512,7 @@ sanei_pio_close (int fd)    return;  } -int  +int  sanei_pio_read (int fd, u_char * buf, int n)  {    if ((0 > fd) && (NELEMS (port) <= fd)) @@ -524,7 +524,7 @@ sanei_pio_read (int fd, u_char * buf, int n)    return pio_read (&port[fd], buf, n);  } -int  +int  sanei_pio_write (int fd, const u_char * buf, int n)  {    if ((0 > fd) && (NELEMS (port) <= fd)) @@ -546,30 +546,30 @@ SANE_Status  sanei_pio_open (const char *dev, int *fdp)  {  	int fp; -	 +  	/* open internal parallel port */  	fp=open("/dev/parallel/parallel1",O_RDWR); -   +    	*fdp=fp;    	if(fp<0) return SANE_STATUS_INVAL;    	return(SANE_STATUS_GOOD);  } -void  +void  sanei_pio_close (int fd)  {  	close(fd);  	return;  } -int  +int  sanei_pio_read (int fd, u_char * buf, int n)  {  	return(read(fd,buf,n));  } -int  +int  sanei_pio_write (int fd, const u_char * buf, int n)  {    	return(write(fd,buf,n)); @@ -585,19 +585,19 @@ sanei_pio_open (const char *dev, int *fdp)  } -void  +void  sanei_pio_close (int fd)  {    return;  } -int  +int  sanei_pio_read (int fd, u_char * buf, int n)  {    return -1;  } -int  +int  sanei_pio_write (int fd, const u_char * buf, int n)  {    return -1; diff --git a/sanei/sanei_pp.c b/sanei/sanei_pp.c index dec84ee..89f3232 100644 --- a/sanei/sanei_pp.c +++ b/sanei/sanei_pp.c @@ -38,7 +38,7 @@   *   * If you write modifications of your own for SANE, it is your choice   * whether to permit this exception to apply to your modifications. - * If you do not wish that, delete this exception notice.  + * If you do not wish that, delete this exception notice.   *   * This file implements an interface for accessing the parallelport   */ @@ -50,7 +50,7 @@   * 3 - things nice to know   * 4 - code flow   * 5 - detailed flow - * 6 - everything  + * 6 - everything   *   * These debug levels can be set using the environment variable   * SANE_DEBUG_SANEI_PP @@ -156,7 +156,7 @@ static unsigned long pp_thresh  = 0;  #if (defined (HAVE_IOPERM) || defined (HAVE_LIBIEEE1284)) && !defined (IO_SUPPORT_MISSING)  typedef struct { -	 +  #ifndef HAVE_LIBIEEE1284  	const char name[6];  	u_long     base;        /**< i/o base address                */ @@ -166,7 +166,7 @@ typedef struct {  	u_int in_use;           /**< port in use?      */  	u_int claimed;          /**< port claimed?     */ -	 +  	int caps;               /**< port capabilities */  } PortRec, *Port; @@ -181,8 +181,8 @@ static PortRec              port[_MAX_PORTS];  /** redefine the CAPability flags */  enum ieee1284_capabilities  { -	CAP1284_RAW    = (1<<0),  -	CAP1284_NIBBLE = (1<<1), /* SPP mode             */  +	CAP1284_RAW    = (1<<0), +	CAP1284_NIBBLE = (1<<1), /* SPP mode             */  	CAP1284_BYTE   = (1<<2), /* PS/2 bidirectional   */  	CAP1284_COMPAT = (1<<3),  	CAP1284_BECP   = (1<<4), @@ -315,12 +315,12 @@ pp_showcaps( int caps )  	char ct[1024];      ct[0] = '\0'; -	 +  	if( caps & CAP1284_NIBBLE ) {  		strcat( ct, "SPP " );  		mode |= SANEI_PP_MODE_SPP;  	} -		 +  	if( caps & CAP1284_BYTE ) {  		strcat( ct, "PS/2 " );  		mode |= SANEI_PP_MODE_BIDI; @@ -330,7 +330,7 @@ pp_showcaps( int caps )  		strcat( ct, "EPP " );  		mode |= SANEI_PP_MODE_EPP;  	} -	 +  	if( caps &  CAP1284_EPPSWE ) {  		strcat( ct, "EPPSWE " );  		mode |= SANEI_PP_MODE_EPP; @@ -357,13 +357,13 @@ pp_showcaps( int caps )  static int  pp_probe( int fd )  { -#ifdef HAVE_IOPL  +#ifdef HAVE_IOPL  	SANE_Byte c;  	int       i, j;  #endif  	SANE_Byte a, b;  	int       retv = 0; -     +  	DBG( 4, "pp_probe: port 0x%04lx\n", port[fd].base );  	/* SPP check */ @@ -383,7 +383,7 @@ pp_probe( int fd )  #ifdef HAVE_IOPL  	/* clear at most 1k of data from FIFO */ -	for( i = 1024; i > 0; i-- ) {  +	for( i = 1024; i > 0; i-- ) {  		a = inbyte402( fd );  		if ((a & 0x03) == 0x03)  			goto no_ecp; @@ -428,7 +428,7 @@ pp_probe( int fd )      	DBG( 4, "pp_probe: ECP with a %i byte FIFO present\n", i );  		retv += CAP1284_ECP;      } -     +  no_ecp:  #endif  	/* check for PS/2 compatible port */ @@ -522,7 +522,7 @@ static int pp_set_scpmode( int fd )  {  	SANE_Byte tmp;  	DBG( 4, "pp_set_scpmode\n" ); -	 +  #ifdef HAVE_IOPL  	tmp  = inbyte402( fd );  	tmp &= 0x1f; @@ -531,7 +531,7 @@ static int pp_set_scpmode( int fd )  	tmp  = inb_ctrl( fd );  	tmp &= 0x0f;  	outb_ctrl ( fd, tmp ); -	 +  	return SANE_STATUS_GOOD;  } @@ -547,7 +547,7 @@ static int pp_set_bidimode( int fd )  	tmp = inb_ctrl( fd );  	tmp = (tmp & 0x0f) | 0x20;  	outb_ctrl ( fd, tmp ); -	 +  	return SANE_STATUS_GOOD;  } @@ -563,7 +563,7 @@ static int pp_set_eppmode( int fd )  	tmp = inb_ctrl( fd );  	tmp = (tmp & 0xf0) | 0x40;  	outb_ctrl ( fd, tmp ); -	 +  	return SANE_STATUS_GOOD;  } @@ -572,7 +572,7 @@ static int pp_set_ecpmode( int fd )  #ifdef HAVE_IOPL  	SANE_Byte tmp;  #endif -	 +  	DBG( 4, "pp_set_ecpmode\n" );  #ifdef HAVE_IOPL  	tmp = inbyte402( fd ); @@ -594,7 +594,7 @@ pp_setmode( int fd, int mode )  		DBG( 2, "pp_setmode: mode not supported %d\n", mode );  		return SANE_STATUS_UNSUPPORTED;  	} -	 +  	switch( mode ) {  		case SANEI_PP_MODE_SPP:  ret = pp_set_scpmode( fd );  break;  		case SANEI_PP_MODE_BIDI: ret = pp_set_bidimode( fd ); break; @@ -715,13 +715,13 @@ pp_init( void )  	}  	DBG( 3, "pp_init: %d ports reported by IEEE 1284 library\n", pplist.portc); -   +  	for( i = 0; i < pplist.portc; i++ )  		DBG( 6, "pp_init: port %d is `%s`\n", i, pplist.portv[i]->name);  	/* we support only up to _MAX_PORTS... */  	if( pplist.portc > _MAX_PORTS ) { -		DBG (1, "pp_init: Lib IEEE 1284 reports too much ports: %d\n",  +		DBG (1, "pp_init: Lib IEEE 1284 reports too much ports: %d\n",  		        pplist.portc );  		ieee1284_free_ports( &pplist ); @@ -759,7 +759,7 @@ pp_open( const char *dev, SANE_Status * status )  #else  	int result;  #endif -   +  	DBG( 4, "pp_open: trying to attach dev `%s`\n", dev );  #if !defined (HAVE_LIBIEEE1284) @@ -853,7 +853,7 @@ pp_open( const char *dev, SANE_Status * status )  	/* TODO: insert FreeBSD compatible code here */  	if( ioperm( port[i].base, 5, 1 )) { -		DBG( 1, "pp_open: cannot get io privilege for port 0x%03lx\n",  +		DBG( 1, "pp_open: cannot get io privilege for port 0x%03lx\n",  				port[i].base);  		port[i].in_use = SANE_FALSE; @@ -867,7 +867,7 @@ pp_open( const char *dev, SANE_Status * status )  	port[i].ecp_ctrl = inbyte402(i);  	port[i].ctrl     = inb_ctrl(i);  #endif -	 +  	/* check the capabilities of this port */  	port[i].caps = pp_probe( i );  #endif @@ -908,7 +908,7 @@ pp_close( int fd, SANE_Status *status )  	if( ioperm( port[fd].base, 5, 0 )) {  #endif  #if defined(HAVE_LIBIEEE1284) -		DBG( 1, "pp_close: can't free port '%s' (%s)\n",  +		DBG( 1, "pp_close: can't free port '%s' (%s)\n",  				pplist.portv[fd]->name, pp_libieee1284_errorstr(result));  #else  		DBG( 1, "pp_close: can't free port 0x%03lx\n", port[fd].base ); @@ -930,7 +930,7 @@ SANE_Status  sanei_pp_init( void )  {  	SANE_Status result; -	 +  	DBG_INIT();  	result = pp_init(); @@ -1008,7 +1008,7 @@ sanei_pp_claim( int fd )  		DBG( 2, "sanei_pp_claim: fd %d is invalid\n", fd );  		return SANE_STATUS_INVAL;  	} -	 +  	result = ieee1284_claim (pplist.portv[fd]);  	if (result) {  		DBG (1, "sanei_pp_claim: failed (%s)\n", @@ -1018,7 +1018,7 @@ sanei_pp_claim( int fd )  #endif  	port[fd].claimed = SANE_TRUE; -	 +  	return SANE_STATUS_GOOD;  } @@ -1032,11 +1032,11 @@ sanei_pp_release( int fd )  		DBG( 2, "sanei_pp_release: fd %d is invalid\n", fd );  		return SANE_STATUS_INVAL;  	} -		 +  	ieee1284_release( pplist.portv[fd] );  #endif  	port[fd].claimed = SANE_FALSE; -	 +  	return SANE_STATUS_GOOD;  } @@ -1121,7 +1121,7 @@ sanei_pp_inb_data( int fd )  {  #ifdef _PARANOIA  	DBG( 4, "sanei_pp_inb_data: called for fd %d\n", fd ); -	 +  #if defined(HAVE_LIBIEEE1284)  	if ((fd < 0) || (fd >= pplist.portc)) {  #else @@ -1139,7 +1139,7 @@ sanei_pp_inb_stat( int fd )  {  #ifdef _PARANOIA  	DBG( 4, "sanei_pp_inb_stat: called for fd %d\n", fd ); -	 +  #if defined(HAVE_LIBIEEE1284)  	if ((fd < 0) || (fd >= pplist.portc)) {  #else @@ -1174,7 +1174,7 @@ sanei_pp_inb_epp( int fd )  {  #ifdef _PARANOIA  	DBG( 4, "sanei_pp_inb_epp: called for fd %d\n", fd ); -	 +  #if defined(HAVE_LIBIEEE1284)  	if ((fd < 0) || (fd >= pplist.portc)) {  #else @@ -1224,7 +1224,7 @@ sanei_pp_setmode( int fd, int mode )  		DBG( 2, "sanei_pp_setmode: invalid mode %d\n", mode );  		return SANE_STATUS_INVAL;  	} -	 +  #if defined(HAVE_LIBIEEE1284)  	switch( mode ) {  		case SANEI_PP_MODE_SPP:  mode = M1284_NIBBLE; break; @@ -1267,7 +1267,7 @@ sanei_pp_udelay( unsigned long usec )  	if( usec < pp_thresh )  		return; -	 +  	do {  		gettimeofday( &now, NULL );  	} while ((now.tv_sec < deadline.tv_sec) || diff --git a/sanei/sanei_pv8630.c b/sanei/sanei_pv8630.c index 848558e..c9bafce 100644 --- a/sanei/sanei_pv8630.c +++ b/sanei/sanei_pv8630.c @@ -5,7 +5,7 @@     Copyright (C) 2001 Marcio Teixeira     This file is part of the SANE package. -  +     This program is free software; you can redistribute it and/or     modify it under the terms of the GNU General Public License as     published by the Free Software Foundation; either version 2 of the diff --git a/sanei/sanei_scsi.c b/sanei/sanei_scsi.c index 2413d8f..b69f78f 100644 --- a/sanei/sanei_scsi.c +++ b/sanei/sanei_scsi.c @@ -252,11 +252,11 @@ static int unit_ready (int fd);  #endif  #if USE == SYSVR4_INTERFACE -# define MAX_DATA 56*1024	/* don't increase or kernel will dump  -				 * tested with adsl, adsa and umax backend  -				 * it depends on the lowend scsi  -				 * drivers . But the most restriction  -				 * is in the UNIXWARE KERNEL witch do  +# define MAX_DATA 56*1024	/* don't increase or kernel will dump +				 * tested with adsl, adsa and umax backend +				 * it depends on the lowend scsi +				 * drivers . But the most restriction +				 * is in the UNIXWARE KERNEL witch do  				 * not allow more then 64kB DMA transfers */  static char lastrcmd[16];	/* hold command block of last read command */  #endif @@ -615,7 +615,7 @@ open_aspi (void)    DBG (1, "OS/2: unique id is    '%s'\n", PSRBlock->u.inq.unique_id);    strcpy (tmpAspi, "asXXXXXX"); -  mktemp (tmpAspi); +  mkstemp (tmpAspi);    DBG (2, "open_aspi: open temporary file '%s'\n", tmpAspi);    tmp = fopen (tmpAspi, "w");    if (!tmp) @@ -875,7 +875,7 @@ sanei_scsi_open (const char *dev, int *fdp,    int fd, i;  #if USE == LINUX_INTERFACE    static int first_time = 1; -#elif USE == MACOSX_INTERFACE   +#elif USE == MACOSX_INTERFACE    UInt8 *guid;    int len;    u_int d; @@ -909,7 +909,7 @@ sanei_scsi_open (const char *dev, int *fdp,           With newer versions of the SG driver, check the available buffer           size by opening all SG device files belonging to a scanner,           issue the ioctl calls for setting and reading the reserved -         buffer size, and take the smallest value.  +         buffer size, and take the smallest value.           For older version of the SG driver, which don't support variable           buffer size, try to read /proc/sys/kernel/sg-big-biff ; if @@ -958,7 +958,7 @@ sanei_scsi_open (const char *dev, int *fdp,      if (sscanf (dev, "b%dt%dl%d", &bus, &target, &lun) != 3)        { -	DBG (1, "sanei_scsi_open: device name `%s´ is not valid: %s\n", +	DBG (1, "sanei_scsi_open: device name `%s´ is not valid: %s\n",  	     dev, strerror (errno));  	return SANE_STATUS_INVAL;        } @@ -1149,7 +1149,7 @@ sanei_scsi_open (const char *dev, int *fdp,  	}        else  	{ -	  DBG (1, "sanei_scsi_open: can't open device `%s´: %s\n", dev, +	  DBG (1, "sanei_scsi_open: can't open device `%s´: %s\n", dev,  	       strerror (errno));  	  return SANE_STATUS_INVAL;  	} @@ -1163,7 +1163,7 @@ sanei_scsi_open (const char *dev, int *fdp,      if (4 !=  	sscanf (dev, "/dev/passthru0:%d,%d,%d,%d", &bus, &cnt, &id, &lun))        { -	DBG (1, "sanei_scsi_open: device name `%s´ is not valid: %s\n", +	DBG (1, "sanei_scsi_open: device name `%s´ is not valid: %s\n",  	     dev, strerror (errno));  	return SANE_STATUS_INVAL;        } @@ -1222,21 +1222,21 @@ sanei_scsi_open (const char *dev, int *fdp,    {  	  char scsi_hca_name[20];  	  u_int hca = 0; -  +  	  if (sscanf (dev, "h%ub%ut%ul%u", &hca, &bus, &target, &lun) != 4)  		  {  			  DBG (1, "sanei_scsi_open: device name %s is not valid\n", dev);  			  return SANE_STATUS_INVAL;  		  } -  +  	  snprintf(scsi_hca_name, 19, "\\\\.\\Scsi%d:", hca);  	  scsi_hca_name[19] = 0; -	   +  	  fd = CreateFile(scsi_hca_name, GENERIC_READ | GENERIC_WRITE,  					  FILE_SHARE_READ | FILE_SHARE_WRITE,  					  NULL, OPEN_EXISTING,  					  FILE_FLAG_RANDOM_ACCESS, NULL ); -	   +  	  if (fd == INVALID_HANDLE_VALUE) fd = -1;    }  #else @@ -1420,7 +1420,7 @@ sanei_scsi_open (const char *dev, int *fdp,      else        {  	/* we have a really old SG driver version, or we're not opening -	   an SG device file  +	   an SG device file  	 */  	if (ioctl (fd, SG_GET_TIMEOUT, &ioctl_val) < 0)  	  { @@ -2436,8 +2436,8 @@ issue (struct req *req)  		  }  #if 0 -		/* Sometimes the Linux SCSI system reports bogus resid values.  -		   Observed with lk 2.4.5, 2.4.13, aic7xxx and sym53c8xx drivers,  +		/* Sometimes the Linux SCSI system reports bogus resid values. +		   Observed with lk 2.4.5, 2.4.13, aic7xxx and sym53c8xx drivers,  		   if command queueing is used. So we better issue only a warning  		 */  		if (status == SANE_STATUS_GOOD) @@ -2601,7 +2601,7 @@ issue (struct req *req)    }    static int			/* Returns 1 if match with 'name' set, else 0 */ -    +      lx_scan_sg (int exclude_devnum, char *name, size_t name_len,  		int host, int channel, int id, int lun)    { @@ -2636,7 +2636,7 @@ issue (struct req *req)    }    static int			/* Returns 1 if match, else 0 */ -    +      lx_chk_devicename (int guess_devnum, char *name, size_t name_len,  		       int host, int channel, int id, int lun)    { @@ -2945,8 +2945,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      char *me = "sanei_scsi_find_devices";      char path[PATH_MAX];      char dev_name[128]; -    struct dirent buf; -    struct dirent *de; +    struct dirent *buf;      DIR *scsidevs;      FILE *fp;      char *ptr; @@ -2987,8 +2986,9 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      number = -1;      for (;;)        { -	ret = readdir_r(scsidevs, &buf, &de); -	if (ret != 0) +	errno = 0; +	buf = readdir (scsidevs); +	if (errno != 0)  	  {  	    DBG (1, "%s: could not read directory %s: %s\n",  		 me, SYSFS_SCSI_DEVICES, strerror(errno)); @@ -2996,14 +2996,14 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	    break;  	  } -	if (de == NULL) +	if (buf == NULL)  	  break; -	if (buf.d_name[0] == '.') +	if (buf->d_name[0] == '.')  	  continue;  	/* Extract bus, channel, id, lun from directory name b:c:i:l */ -	ptr = buf.d_name; +	ptr = buf->d_name;  	for (i = 0; i < 4; i++)  	  {  	    errno = 0; @@ -3028,7 +3028,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	    if (*end && (*end != ':'))  	      { -		DBG (1, "%s: parse error on string %s (%d)\n", me, buf.d_name, i); +		DBG (1, "%s: parse error on string %s (%d)\n", me, buf->d_name, i);  		i = 12; /* Skip */  		break; @@ -3036,7 +3036,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	    if (val > INT_MAX)  	      { -		DBG (1, "%s: integer value too large (%s)\n", me, buf.d_name); +		DBG (1, "%s: integer value too large (%s)\n", me, buf->d_name);  		i = 12; /* Skip */  		break; @@ -3059,11 +3059,11 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	for (i = 0; i < 3; i++)  	  {  	    ret = snprintf (path, PATH_MAX, "%s/%s/%s", -			   SYSFS_SCSI_DEVICES, buf.d_name, vmtfiles[i]); +			   SYSFS_SCSI_DEVICES, buf->d_name, vmtfiles[i]);  	    if ((ret < 0) || (ret >= PATH_MAX))  	      {  		DBG (1, "%s: skipping %s/%s, PATH_MAX exceeded on %s\n", -		     me, SYSFS_SCSI_DEVICES, buf.d_name, vmtfiles[i]); +		     me, SYSFS_SCSI_DEVICES, buf->d_name, vmtfiles[i]);  		i = 12; /* Skip */  		break; @@ -3179,7 +3179,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      scsireq_t hdr;      int result; -/* xxx obsolete:  +/* xxx obsolete:    cdb_size = CDB_SIZE (*(u_char *) src);  */ @@ -3201,7 +3201,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	/* The old variant:  	   hdr.databuf = (char *) src + cdb_size;  	   hdr.datalen = src_size; -	   xxxxxx huh? Shouldn´t the above line have been src_size - cdb_size) +	   xxxxxx huh? Shouldn´t the above line have been src_size - cdb_size)  	 */  	hdr.databuf = (char *) src;  	hdr.datalen = src_size; @@ -3271,8 +3271,8 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      ccb = cam_getccb (dev);      /* Build the CCB */ -    bzero (&(&ccb->ccb_h)[1], sizeof (struct ccb_scsiio)); -    bcopy (cmd, &ccb->csio.cdb_io.cdb_bytes, cmd_size); +    memset (&(&ccb->ccb_h)[1], 0, sizeof (struct ccb_scsiio)); +    memcpy (&ccb->csio.cdb_io.cdb_bytes, cmd, cmd_size);      /*       * Set the data direction flags. @@ -3368,7 +3368,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      int retval = 0;      /* build ccb for device match */ -    bzero (&cdm, sizeof (cdm)); +    memset (&cdm, 0, sizeof (cdm));      cdm.ccb_h.func_code = XPT_DEV_MATCH;      /* result buffer */ @@ -3454,7 +3454,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,        }      /* build ccb for device match */ -    bzero (&cdm, sizeof (cdm)); +    memset (&cdm, 0, sizeof (cdm));      cdm.ccb_h.func_code = XPT_DEV_MATCH;      /* result buffer */ @@ -4449,7 +4449,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	memcpy (databuf, (u_char *) src, src_size);        } -    bzero (sensebuf, 128); +    memset (sensebuf, 0, 128);      /*       * Do SCSI request... @@ -5013,7 +5013,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  #if USE == WIN32_INTERFACE  SANE_Status -sanei_scsi_cmd2 (int fd,  +sanei_scsi_cmd2 (int fd,                  const void *cmd, size_t cmd_size,                  const void *src, size_t src_size,  		void *dst, size_t * dst_size) @@ -5049,8 +5049,8 @@ sanei_scsi_cmd2 (int fd,          pkt.sptd.DataBuffer         = src;      }    else { -       pkt.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED;  -  }	 +       pkt.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; +  }    pkt.sptd.TimeOutValue       = sane_scsicmd_timeout; @@ -5081,7 +5081,7 @@ sanei_scsi_cmd2 (int fd,        else {  	 return SANE_STATUS_IO_ERROR;        } -   }  +   }     else if (pkt.sptd.ScsiStatus != 0) {        DBG (1, "sanei_scsi_cmd2: ScsiStatus is %d\n",  	    pkt.sptd.ScsiStatus); @@ -5152,14 +5152,14 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	adapter = (PSCSI_ADAPTER_BUS_INFO)buffer; -	for(i = 0; i < adapter->NumberOfBuses; i++) {	 +	for(i = 0; i < adapter->NumberOfBuses; i++) {  		if (adapter->BusData[i].InquiryDataOffset == 0) {  			/* No device here */  			continue;  		} -		inquiry = (PSCSI_INQUIRY_DATA) (buffer +  +		inquiry = (PSCSI_INQUIRY_DATA) (buffer +                                     adapter->BusData[i].InquiryDataOffset);  		while(1) { @@ -5358,7 +5358,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      memcpy (&cdb.cdb, cmd, cmd_size);      if (dst && dst_size)        { -	bzero (dst, *dst_size); +	memset (dst, 0, *dst_size);  	range.address = (IOVirtualAddress) dst;  	range.length = *dst_size;  	transferCount = *dst_size; @@ -5699,7 +5699,7 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,  	DBG (6, "isRead dst_size:%ld\n", *dst_size);  	/* Zero the buffer. */ -	bzero (dst, *dst_size); +	memset (dst, 0, *dst_size);  	/* Configure the virtual range for the buffer. */  	range.address = (long) dst; @@ -5722,8 +5722,8 @@ sanei_scsi_find_devices (const char *findvendor, const char *findmodel,      /* zero the senseData and CDB */ -    bzero (&senseData, sizeof (senseData)); -    bzero (cdb, sizeof (cdb)); +    memset (&senseData, 0, sizeof (senseData)); +    memset (cdb, 0, sizeof (cdb));      /* copy the command data */      memcpy (cdb, cmd, cmd_size); diff --git a/sanei/sanei_thread.c b/sanei/sanei_thread.c index fcf52c1..f701423 100644 --- a/sanei/sanei_thread.c +++ b/sanei/sanei_thread.c @@ -115,20 +115,22 @@ sanei_thread_is_forked( void )  /* Use this to mark a SANE_Pid as invaild instead of marking with -1.   */ +#ifdef USE_PTHREAD  static void  sanei_thread_set_invalid( SANE_Pid *pid )  {  #ifdef WIN32  #ifdef WINPTHREAD_API -	*pid = 0; +	*pid = (pthread_t) 0;  #else  	pid->p = 0;  #endif  #else -	*pid = -1; +	*pid = (pthread_t) -1;  #endif  } +#endif  /* Return if PID is a valid PID or not. */  SANE_Bool @@ -162,12 +164,12 @@ sanei_thread_pid_to_long( SANE_Pid pid )  #ifdef WIN32  #ifdef WINPTHREAD_API -	rc = pid; +	rc = (long) pid;  #else  	rc = pid.p;  #endif  #else -	rc = pid; +	rc = (long) pid;  #endif  	return rc; @@ -225,7 +227,7 @@ sanei_thread_begin( int (*func)(void *args), void* args )  		DBG( 1, "_beginthread() failed\n" );  		return -1;  	} -    +  	DBG( 2, "_beginthread() created thread %d\n", pid );  	return pid;  } @@ -282,7 +284,7 @@ sanei_thread_begin( int (*func)(void *args), void* args )  		DBG( 1, "resume_thread() failed\n" );  		return -1;  	} -    +  	DBG( 2, "spawn_thread() created thread %d\n", pid );  	return pid;  } @@ -374,7 +376,7 @@ restore_sigpipe( void )  			sigemptyset( &act.sa_mask );  			act.sa_flags   = 0;  			act.sa_handler = SIG_DFL; -			 +  			DBG( 2, "restoring SIGPIPE to SIG_DFL\n" );  			sigaction( SIGPIPE, &act, NULL );  		} @@ -443,7 +445,7 @@ sanei_thread_begin( int (func)(void *args), void* args )  	}  	else  		DBG( 2, "pthread_create() created thread %ld\n", -		     (SANE_Pid)thread ); +		     sanei_thread_pid_to_long(thread) );  	return (SANE_Pid)thread;  #else @@ -458,7 +460,7 @@ sanei_thread_begin( int (func)(void *args), void* args )      	/* run in child context... */  		int status = func( args ); -		 +  		/* don't use exit() since that would run the atexit() handlers */  		_exit( status );  	} @@ -511,10 +513,11 @@ sanei_thread_waitpid( SANE_Pid pid, int *status )  	}  	if ( EDEADLK == rc ) {  		if ( (pthread_t)pid != pthread_self() ) { -			/* call detach in any case to make sure that the thread resources  +			/* call detach in any case to make sure that the thread resources  			 * will be freed, when the thread has terminated  			 */ -			DBG(2, "* detaching thread(%ld)\n", pid ); +			DBG(2, "* detaching thread(%ld)\n", +			    sanei_thread_pid_to_long(pid) );  			pthread_detach((pthread_t)pid);  		}  	} diff --git a/sanei/sanei_udp.c b/sanei/sanei_udp.c index ab316ea..b5bb8cc 100644 --- a/sanei/sanei_udp.c +++ b/sanei/sanei_udp.c @@ -229,4 +229,3 @@ sanei_udp_recvfrom(int fd, u_char * buf, int count, char **fromp)  	return l;  } - diff --git a/sanei/sanei_usb.c b/sanei/sanei_usb.c index e4b23dc..db0f452 100644 --- a/sanei/sanei_usb.c +++ b/sanei/sanei_usb.c @@ -49,6 +49,7 @@  #include "../include/sane/config.h"  #include <stdlib.h> +#include <ctype.h>  #include <sys/types.h>  #include <sys/stat.h>  #include <fcntl.h> @@ -62,6 +63,9 @@  #include <dirent.h>  #include <time.h> +#if WITH_USB_RECORD_REPLAY +#include <libxml/tree.h> +#endif  #ifdef HAVE_RESMGR  #include <resmgr.h> @@ -174,6 +178,34 @@ static int device_number=0;   * count number of time sanei_usb has been initialized */  static int initialized=0; +typedef enum +{ +  sanei_usb_testing_mode_disabled = 0, + +  sanei_usb_testing_mode_record, // records the communication with the slave +                                 // but does not change the USB stack in any +                                 // way +  sanei_usb_testing_mode_replay,  // replays the communication with the scanner +                                  // recorded earlier +} +sanei_usb_testing_mode; + +// Whether testing mode has been enabled +static sanei_usb_testing_mode testing_mode = sanei_usb_testing_mode_disabled; + +#if WITH_USB_RECORD_REPLAY +static int testing_development_mode = 0; +int testing_known_commands_input_failed = 0; +unsigned testing_last_known_seq = 0; +SANE_String testing_record_backend = NULL; +xmlNode* testing_append_commands_node = NULL; + +// XML file from which we read testing data +SANE_String testing_xml_path = NULL; +xmlDoc* testing_xml_doc = NULL; +xmlNode* testing_xml_next_tx_node = NULL; +#endif // WITH_USB_RECORD_REPLAY +  #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)  static int libusb_timeout = 30 * 1000;	/* 30 seconds */  #endif /* HAVE_LIBUSB_LEGACY */ @@ -455,6 +487,859 @@ sanei_libusb_strerror (int errcode)  }  #endif /* HAVE_LIBUSB */ +#if WITH_USB_RECORD_REPLAY +SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path, +                                            int development_mode) +{ +  testing_mode = sanei_usb_testing_mode_replay; +  testing_development_mode = development_mode; + +  // TODO: we'll leak if noone ever inits sane_usb properly +  testing_xml_path = strdup(path); +  testing_xml_doc = xmlReadFile(testing_xml_path, NULL, 0); +  if (!testing_xml_doc) +    return SANE_STATUS_ACCESS_DENIED; + +  return SANE_STATUS_GOOD; +} + +#define FAIL_TEST(func, ...)                                                   \ +  do {                                                                         \ +    DBG(1, "%s: FAIL: ", func);                                                \ +    DBG(1, __VA_ARGS__);                                                       \ +    fail_test();                                                               \ +  } while (0) + +#define FAIL_TEST_TX(func, node, ...)                                          \ +  do {                                                                         \ +    sanei_xml_print_seq_if_any(node, func);                                    \ +    DBG(1, "%s: FAIL: ", func);                                                \ +    DBG(1, __VA_ARGS__);                                                       \ +    fail_test();                                                               \ +  } while (0) + +void fail_test() +{ +} + +SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name) +{ +  testing_mode = sanei_usb_testing_mode_record; +  testing_record_backend = strdup(be_name); +  testing_xml_path = strdup(path); + +  return SANE_STATUS_GOOD; +} + +static xmlNode* sanei_xml_find_first_child_with_name(xmlNode* parent, +                                                     const char* name) +{ +  xmlNode* curr_child = xmlFirstElementChild(parent); +  while (curr_child != NULL) +    { +      if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0) +        return curr_child; +      curr_child = xmlNextElementSibling(curr_child); +    } +  return NULL; +} + +static xmlNode* sanei_xml_find_next_child_with_name(xmlNode* child, +                                                    const char* name) +{ +  xmlNode* curr_child = xmlNextElementSibling(child); +  while (curr_child != NULL) +    { +      if (xmlStrcmp(curr_child->name, (const xmlChar*)name) == 0) +        return curr_child; +      curr_child = xmlNextElementSibling(curr_child); +    } +  return NULL; +} + +// a wrapper to get rid of -Wpointer-sign warnings in a single place +static char* sanei_xml_get_prop(xmlNode* node, const char* name) +{ +  return (char*)xmlGetProp(node, (const xmlChar*)name); +} + +// returns -1 if attribute is not found +static int sanei_xml_get_prop_uint(xmlNode* node, const char* name) +{ +  char* attr = sanei_xml_get_prop(node, name); +  if (attr == NULL) +    { +      return -1; +    } + +  unsigned attr_uint = strtoul(attr, NULL, 0); +  xmlFree(attr); +  return attr_uint; +} + +static void sanei_xml_print_seq_if_any(xmlNode* node, const char* parent_fun) +{ +  char* attr = sanei_xml_get_prop(node, "seq"); +  if (attr == NULL) +    return; + +  DBG(1, "%s: FAIL: in transaction with seq %s:\n", parent_fun, attr); +  xmlFree(attr); +} + +// Checks whether transaction should be ignored. We ignore get_descriptor and +// set_configuration transactions. The latter is ignored because +// set_configuration is called in sanei_usb_open outside test path. +static int sanei_xml_is_transaction_ignored(xmlNode* node) +{ +  if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) +    return 0; + +  if (sanei_xml_get_prop_uint(node, "endpoint_number") != 0) +    return 0; + +  int is_direction_in = 0; +  int is_direction_out = 0; + +  char* attr = sanei_xml_get_prop(node, "direction"); +  if (attr == NULL) +    return 0; + +  if (strcmp(attr, "IN") == 0) +    is_direction_in = 1; +  if (strcmp(attr, "OUT") == 0) +    is_direction_out = 1; +  xmlFree(attr); + +  unsigned bRequest = sanei_xml_get_prop_uint(node, "bRequest"); +  if (bRequest == USB_REQ_GET_DESCRIPTOR && is_direction_in) +    { +      if (sanei_xml_get_prop_uint(node, "bmRequestType") != 0x80) +        return 0; +      return 1; +    } +  if (bRequest == USB_REQ_SET_CONFIGURATION && is_direction_out) +    return 1; + +  return 0; +} + +static xmlNode* sanei_xml_skip_non_tx_nodes(xmlNode* node) +{ +  const char* known_node_names[] = { +    "control_tx", "bulk_tx", "interrupt_tx", "debug", "known_commands_end" +  }; + +  while (node != NULL) +    { +      int found = 0; +      for (unsigned i = 0; i < sizeof(known_node_names) / +                               sizeof(known_node_names[0]); ++i) +        { +          if (xmlStrcmp(node->name, (const xmlChar*) known_node_names[i]) == 0) +            { +              found = 1; +              break; +            } +        } + +      if (found && sanei_xml_is_transaction_ignored(node) == 0) +        { +          break; +        } + +      node = xmlNextElementSibling(node); +    } +  return node; +} + +static int sanei_xml_is_known_commands_end(xmlNode* node) +{ +  if (!testing_development_mode || node == NULL) +    return 0; +  return xmlStrcmp(node->name, (const xmlChar*)"known_commands_end") == 0; +} + +// returns next transaction node that is not get_descriptor +static xmlNode* sanei_xml_peek_next_tx_node() +{ +  return testing_xml_next_tx_node; +} + +// returns next transaction node that is not get_descriptor +static xmlNode* sanei_xml_get_next_tx_node() +{ +  xmlNode* next = testing_xml_next_tx_node; + +  if (sanei_xml_is_known_commands_end(next)) +    { +      testing_append_commands_node = xmlPreviousElementSibling(next); +      return next; +    } + +  testing_xml_next_tx_node = +      xmlNextElementSibling(testing_xml_next_tx_node); + +  testing_xml_next_tx_node = +      sanei_xml_skip_non_tx_nodes(testing_xml_next_tx_node); + +  return next; +} + +#define CHAR_TYPE_INVALID -1 +#define CHAR_TYPE_SPACE -2 + +static int8_t sanei_xml_char_types[256] = +{ +  /* 0x00-0x0f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, +  /* 0x10-0x1f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x20-0x2f */ -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x30-0x3f */  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, +  /* 0x40-0x4f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x50-0x5f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x60-0x6f */ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x70-0x7f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x80-0x8f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0x90-0x9f */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xa0-0xaf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xb0-0xbf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xc0-0xcf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xd0-0xdf */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xe0-0xef */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +  /* 0xf0-0xff */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +}; + +static char* sanei_xml_get_hex_data_slow_path(xmlNode* node, xmlChar* content, xmlChar* cur_content, +                                              char* ret_data, char* cur_ret_data, size_t* size) +{ +  int num_nibbles = 0; +  unsigned cur_nibble = 0; + +  while (*cur_content != 0) +    { +      while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) +        cur_content++; + +      if (*cur_content == 0) +        break; + +      // don't use stroul because it will parse in big-endian and data is in +      // little endian +      uint8_t c = *cur_content; +      int8_t ci = sanei_xml_char_types[c]; +      if (ci == CHAR_TYPE_INVALID) +        { +          FAIL_TEST_TX(__func__, node, "unexpected character %c\n", c); +          cur_content++; +          continue; +        } + +      cur_nibble = (cur_nibble << 4) | ci; +      num_nibbles++; + +      if (num_nibbles == 2) +        { +          *cur_ret_data++ = cur_nibble; +          cur_nibble = 0; +          num_nibbles = 0; +        } +      cur_content++; +    } +  *size = cur_ret_data - ret_data; +  xmlFree(content); +  return ret_data; +} + +// Parses hex data in XML text node in the format of '00 11 ab 3f', etc. to +// binary string. The size is returned as *size. The caller is responsible for +// freeing the returned value +static char* sanei_xml_get_hex_data(xmlNode* node, size_t* size) +{ +  xmlChar* content = xmlNodeGetContent(node); + +  // let's overallocate to simplify the implementation. We expect the string +  // to be deallocated soon anyway +  char* ret_data = malloc(strlen((const char*)content) / 2 + 2); +  char* cur_ret_data = ret_data; + +  xmlChar* cur_content = content; + +  // the text to binary conversion takes most of the time spent in tests, so we +  // take extra care to optimize it. We split the implementation into fast and +  // slow path. The fast path utilizes the knowledge that there will be no spaces +  // within bytes. When this assumption does not hold, we switch to the slow path. +  while (*cur_content != 0) +    { +      // most of the time there will be 1 or 2 spaces between bytes. Give the CPU +      // chance to predict this by partially unrolling the while loop. +      if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) +        { +          cur_content++; +          if (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) +            { +              cur_content++; +              while (sanei_xml_char_types[(uint8_t)*cur_content] == CHAR_TYPE_SPACE) +                cur_content++; +            } +        } + +      if (*cur_content == 0) +        break; + +      // don't use stroul because it will parse in big-endian and data is in +      // little endian +      int8_t ci1 = sanei_xml_char_types[(uint8_t)*cur_content]; +      int8_t ci2 = sanei_xml_char_types[(uint8_t)*(cur_content + 1)]; + +      if (ci1 < 0 || ci2 < 0) +        return sanei_xml_get_hex_data_slow_path(node, content, cur_content, ret_data, cur_ret_data, +                                                size); + +      *cur_ret_data++ = ci1 << 4 | ci2; +      cur_content += 2; +    } +  *size = cur_ret_data - ret_data; +  xmlFree(content); +  return ret_data; +} + +// caller is responsible for freeing the returned pointer +static char* sanei_binary_to_hex_data(const char* data, size_t size, +                                      size_t* out_size) +{ +  char* hex_data = malloc(size * 4); +  size_t hex_size = 0; + +  for (size_t i = 0; i < size; ++i) +    { +      hex_size += snprintf(hex_data + hex_size, 3, "%02hhx", data[i]); +      if (i + 1 != size) +      { +        if ((i + 1) % 32 == 0) +          hex_data[hex_size++] = '\n'; +        else +          hex_data[hex_size++] = ' '; +      } +    } +  hex_data[hex_size] = 0; +  if (out_size) +    *out_size = hex_size; +  return hex_data; +} + + +static void sanei_xml_set_data(xmlNode* node, const char* data) +{ +  // FIXME: remove existing children +  xmlAddChild(node, xmlNewText((const xmlChar*)data)); +} + +// Writes binary data to XML node as a child text node in the hex format of +// '00 11 ab 3f'. +static void sanei_xml_set_hex_data(xmlNode* node, const char* data, +                                   size_t size) +{ +  char* hex_data = sanei_binary_to_hex_data(data, size, NULL); +  sanei_xml_set_data(node, hex_data); +  free(hex_data); +} + +static void sanei_xml_set_hex_attr(xmlNode* node, const char* attr_name, +                                   unsigned attr_value) +{ +  const int buf_size = 128; +  char buf[buf_size]; +  if (attr_value > 0xffffff) +    snprintf(buf, buf_size, "0x%x", attr_value); +  else if (attr_value > 0xffff) +    snprintf(buf, buf_size, "0x%06x", attr_value); +  else if (attr_value > 0xff) +    snprintf(buf, buf_size, "0x%04x", attr_value); +  else +    snprintf(buf, buf_size, "0x%02x", attr_value); + +  xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf); +} + +static void sanei_xml_set_uint_attr(xmlNode* node, const char* attr_name, +                                    unsigned attr_value) +{ +  const int buf_size = 128; +  char buf[buf_size]; +  snprintf(buf, buf_size, "%d", attr_value); +  xmlNewProp(node, (const xmlChar*)attr_name, (const xmlChar*)buf); +} + +static xmlNode* sanei_xml_append_command(xmlNode* sibling, +                                         int indent, xmlNode* e_command) +{ +  if (indent) +    { +      xmlNode* e_indent = xmlNewText((const xmlChar*)"\n    "); +      sibling = xmlAddNextSibling(sibling, e_indent); +    } +  return xmlAddNextSibling(sibling, e_command); +} + +static void sanei_xml_command_common_props(xmlNode* node, int endpoint_number, +                                           const char* direction) +{ +  xmlNewProp(node, (const xmlChar*)"time_usec", (const xmlChar*)"0"); +  sanei_xml_set_uint_attr(node, "seq", ++testing_last_known_seq); +  sanei_xml_set_uint_attr(node, "endpoint_number", endpoint_number); +  xmlNewProp(node, (const xmlChar*)"direction", (const xmlChar*)direction); +} + +static void sanei_xml_record_seq(xmlNode* node) +{ +  int seq = sanei_xml_get_prop_uint(node, "seq"); +  if (seq > 0) +    testing_last_known_seq = seq; +} + +static void sanei_xml_break() +{ +} + +static void sanei_xml_break_if_needed(xmlNode* node) +{ +  char* attr = sanei_xml_get_prop(node, "debug_break"); +  if (attr != NULL) +    { +      sanei_xml_break(); +      xmlFree(attr); +    } +} + +// returns 1 on success +static int sanei_usb_check_attr(xmlNode* node, const char* attr_name, +                                const char* expected, const char* parent_fun) +{ +  char* attr = sanei_xml_get_prop(node, attr_name); +  if (attr == NULL) +    { +      FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name); +      return 0; +    } + +  if (strcmp(attr, expected) != 0) +    { +      FAIL_TEST_TX(parent_fun, node, "unexpected %s attribute: %s, wanted %s\n", +                   attr_name, attr, expected); +      xmlFree(attr); +      return 0; +    } +  xmlFree(attr); +  return 1; +} + +// returns 1 on success +static int sanei_usb_attr_is(xmlNode* node, const char* attr_name, +                             const char* expected) +{ +  char* attr = sanei_xml_get_prop(node, attr_name); +  if (attr == NULL) +      return 0; + +  if (strcmp(attr, expected) != 0) +    { +      xmlFree(attr); +      return 0; +    } +  xmlFree(attr); +  return 1; +} + +// returns 0 on success +static int sanei_usb_check_attr_uint(xmlNode* node, const char* attr_name, +                                     unsigned expected, const char* parent_fun) +{ +  char* attr = sanei_xml_get_prop(node, attr_name); +  if (attr == NULL) +    { +      FAIL_TEST_TX(parent_fun, node, "no %s attribute\n", attr_name); +      return 0; +    } + +  unsigned attr_int = strtoul(attr, NULL, 0); +  if (attr_int != expected) +    { +      FAIL_TEST_TX(parent_fun, node, +                   "unexpected %s attribute: %s, wanted 0x%x\n", +                   attr_name, attr, expected); +      xmlFree(attr); +      return 0; +    } +  xmlFree(attr); +  return 1; +} + +static int sanei_usb_attr_is_uint(xmlNode* node, const char* attr_name, +                                  unsigned expected) +{ +  char* attr = sanei_xml_get_prop(node, attr_name); +  if (attr == NULL) +    return 0; + +  unsigned attr_int = strtoul(attr, NULL, 0); +  if (attr_int != expected) +    { +      xmlFree(attr); +      return 0; +    } +  xmlFree(attr); +  return 1; +} + +// returns 1 on data equality +static int sanei_usb_check_data_equal(xmlNode* node, +                                      const char* data, +                                      size_t data_size, +                                      const char* expected_data, +                                      size_t expected_size, +                                      const char* parent_fun) +{ +  if ((data_size == expected_size) && +      (memcmp(data, expected_data, data_size) == 0)) +    return 1; + +  char* data_hex = sanei_binary_to_hex_data(data, data_size, NULL); +  char* expected_hex = sanei_binary_to_hex_data(expected_data, expected_size, +                                                NULL); + +  if (data_size == expected_size) +    FAIL_TEST_TX(parent_fun, node, "data differs (size %lu):\n", data_size); +  else +    FAIL_TEST_TX(parent_fun, node, +                 "data differs (got size %lu, expected %lu):\n", +                 data_size, expected_size); + +  FAIL_TEST(parent_fun, "got: %s\n", data_hex); +  FAIL_TEST(parent_fun, "expected: %s\n", expected_hex); +  free(data_hex); +  free(expected_hex); +  return 0; +} + +SANE_String sanei_usb_testing_get_backend() +{ +  if (testing_xml_doc == NULL) +    return NULL; + +  xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc); +  if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0) +    { +      FAIL_TEST(__func__, "the given file is not USB capture\n"); +      return NULL; +    } + +  char* attr = sanei_xml_get_prop(el_root, "backend"); +  if (attr == NULL) +    { +      FAIL_TEST(__func__, "no backend attr in description node\n"); +      return NULL; +    } +  // duplicate using strdup so that the caller can use free() +  char* ret = strdup(attr); +  xmlFree(attr); +  return ret; +} + +SANE_Bool sanei_usb_is_replay_mode_enabled() +{ +  if (testing_mode == sanei_usb_testing_mode_replay) +    return SANE_TRUE; + +  return SANE_FALSE; +} + +static void sanei_usb_record_debug_msg(xmlNode* node, SANE_String_Const message) +{ +  int node_was_null = node == NULL; +  if (node_was_null) +    node = testing_append_commands_node; + +  xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"debug"); +  sanei_xml_set_uint_attr(e_tx, "seq", ++testing_last_known_seq); +  xmlNewProp(e_tx, (const xmlChar*)"message", (const xmlChar*)message); + +  node = sanei_xml_append_command(node, node_was_null, e_tx); + +  if (node_was_null) +    testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_debug_msg(xmlNode* node, SANE_String_Const message) +{ +  if (!testing_development_mode) +    return; + +  testing_last_known_seq--; +  sanei_usb_record_debug_msg(node, message); +  xmlUnlinkNode(node); +  xmlFreeNode(node); +} + +static void sanei_usb_replay_debug_msg(SANE_String_Const message) +{ +  if (testing_known_commands_input_failed) +    return; + +  xmlNode* node = sanei_xml_get_next_tx_node(); +  if (node == NULL) +    { +      FAIL_TEST(__func__, "no more transactions\n"); +      return; +    } + +  if (sanei_xml_is_known_commands_end(node)) +    { +      sanei_usb_record_debug_msg(NULL, message); +      return; +    } + +  sanei_xml_record_seq(node); +  sanei_xml_break_if_needed(node); + +  if (xmlStrcmp(node->name, (const xmlChar*)"debug") != 0) +    { +      FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                   (const char*) node->name); +      sanei_usb_record_replace_debug_msg(node, message); +    } + +  if (!sanei_usb_check_attr(node, "message", message, __func__)) +    { +      sanei_usb_record_replace_debug_msg(node, message); +    } +} + +extern void sanei_usb_testing_record_message(SANE_String_Const message) +{ +  if (testing_mode == sanei_usb_testing_mode_record) +    { +      sanei_usb_record_debug_msg(NULL, message); +    } +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      sanei_usb_replay_debug_msg(message); +    } +} + +static void sanei_usb_add_endpoint(device_list_type* device, +                                   SANE_Int transfer_type, +                                   SANE_Int ep_address, +                                   SANE_Int ep_direction); + +static SANE_Status sanei_usb_testing_init() +{ +  DBG_INIT(); + +  if (testing_mode == sanei_usb_testing_mode_record) +    { +      testing_xml_doc = xmlNewDoc((const xmlChar*)"1.0"); +      return SANE_STATUS_GOOD; +    } + +  if (device_number != 0) +    return SANE_STATUS_INVAL; // already opened + +  xmlNode* el_root = xmlDocGetRootElement(testing_xml_doc); +  if (xmlStrcmp(el_root->name, (const xmlChar*)"device_capture") != 0) +    { +      DBG(1, "%s: the given file is not USB capture\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  xmlNode* el_description = +      sanei_xml_find_first_child_with_name(el_root, "description"); +  if (el_description == NULL) +    { +      DBG(1, "%s: could not find description node\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  int device_id = sanei_xml_get_prop_uint(el_description, "id_vendor"); +  if (device_id < 0) +    { +      DBG(1, "%s: no id_vendor attr in description node\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  int product_id = sanei_xml_get_prop_uint(el_description, "id_product"); +  if (product_id < 0) +    { +      DBG(1, "%s: no id_product attr in description node\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  xmlNode* el_configurations = +      sanei_xml_find_first_child_with_name(el_description, "configurations"); +  if (el_configurations == NULL) +    { +      DBG(1, "%s: could not find configurations node\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  xmlNode* el_configuration = +      sanei_xml_find_first_child_with_name(el_configurations, "configuration"); +  if (el_configuration == NULL) +    { +      DBG(1, "%s: no configuration nodes\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  while (el_configuration != NULL) +    { +      xmlNode* el_interface = +          sanei_xml_find_first_child_with_name(el_configuration, "interface"); + +      while (el_interface != NULL) +        { +          device_list_type device; +          memset(&device, 0, sizeof(device)); +          device.devname = strdup(testing_xml_path); + +          // other code shouldn't depend on methon because testing_mode is +          // sanei_usb_testing_mode_replay +          device.method = sanei_usb_method_libusb; +          device.vendor = device_id; +          device.product = product_id; + +          device.interface_nr = sanei_xml_get_prop_uint(el_interface, "number"); +          if (device.interface_nr < 0) +            { +              DBG(1, "%s: no number attr in interface node\n", __func__); +              return SANE_STATUS_INVAL; +            } + +          xmlNode* el_endpoint = +              sanei_xml_find_first_child_with_name(el_interface, "endpoint"); + +          while (el_endpoint != NULL) +            { +              char* transfer_attr = sanei_xml_get_prop(el_endpoint, +                                                       "transfer_type"); +              int address = sanei_xml_get_prop_uint(el_endpoint, "address"); +              char* direction_attr = sanei_xml_get_prop(el_endpoint, +                                                        "direction"); + +              int direction_is_in = strcmp(direction_attr, "IN") == 0 ? 1 : 0; +              int transfer_type = -1; +              if (strcmp(transfer_attr, "INTERRUPT") == 0) +                transfer_type = USB_ENDPOINT_TYPE_INTERRUPT; +              else if (strcmp(transfer_attr, "BULK") == 0) +                transfer_type = USB_ENDPOINT_TYPE_BULK; +              else if (strcmp(transfer_attr, "ISOCHRONOUS") == 0) +                transfer_type = USB_ENDPOINT_TYPE_ISOCHRONOUS; +              else if (strcmp(transfer_attr, "CONTROL") == 0) +                transfer_type = USB_ENDPOINT_TYPE_CONTROL; +              else +                { +                  DBG(3, "%s: unknown endpoint type %s\n", +                      __func__, transfer_attr); +                } + +              if (transfer_type >= 0) +                { +                  sanei_usb_add_endpoint(&device, transfer_type, address, +                                         direction_is_in); +                } + +              xmlFree(transfer_attr); +              xmlFree(direction_attr); + +              el_endpoint = +                  sanei_xml_find_next_child_with_name(el_endpoint, "endpoint"); +            } +          device.alt_setting = 0; +          device.missing = 0; + +          memcpy(&(devices[device_number]), &device, sizeof(device)); +          device_number++; + +          el_interface = sanei_xml_find_next_child_with_name(el_interface, +                                                             "interface"); +        } +      el_configuration = +            sanei_xml_find_next_child_with_name(el_configurations, +                                                "configuration"); +    } + +  xmlNode* el_transactions = +      sanei_xml_find_first_child_with_name(el_root, "transactions"); + +  if (el_transactions == NULL) +    { +      DBG(1, "%s: could not find transactions node\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  xmlNode* el_transaction = xmlFirstElementChild(el_transactions); +  el_transaction = sanei_xml_skip_non_tx_nodes(el_transaction); + +  if (el_transaction == NULL) +    { +      DBG(1, "%s: no transactions within capture\n", __func__); +      return SANE_STATUS_INVAL; +    } + +  testing_xml_next_tx_node = el_transaction; + +  return SANE_STATUS_GOOD; +} + +static void sanei_usb_testing_exit() +{ +  if (testing_development_mode || testing_mode == sanei_usb_testing_mode_record) +    { +      if (testing_mode == sanei_usb_testing_mode_record) +        { +          xmlAddNextSibling(testing_append_commands_node, xmlNewText((const xmlChar*)"\n  ")); +          free(testing_record_backend); +        } +      xmlSaveFileEnc(testing_xml_path, testing_xml_doc, "UTF-8"); +    } +  xmlFreeDoc(testing_xml_doc); +  free(testing_xml_path); +  xmlCleanupParser(); +} +#else // WITH_USB_RECORD_REPLAY +SANE_Status sanei_usb_testing_enable_replay(SANE_String_Const path, +                                            int development_mode) +{ +  (void) path; +  (void) development_mode; + +  DBG(1, "USB record-replay mode support is missing\n"); +  return SANE_STATUS_UNSUPPORTED; +} + +SANE_Status sanei_usb_testing_enable_record(SANE_String_Const path, SANE_String_Const be_name) +{ +  (void) path; +  (void) be_name; + +  DBG(1, "USB record-replay mode support is missing\n"); +  return SANE_STATUS_UNSUPPORTED; +} + +SANE_String sanei_usb_testing_get_backend() +{ +  return NULL; +} + +SANE_Bool sanei_usb_is_replay_mode_enabled() +{ +  return SANE_FALSE; +} + +void sanei_usb_testing_record_message(SANE_String_Const message) +{ +  (void) message; +} +#endif // WITH_USB_RECORD_REPLAY +  void  sanei_usb_init (void)  { @@ -473,6 +1358,26 @@ sanei_usb_init (void)    if(device_number==0)      memset (devices, 0, sizeof (devices)); +#if WITH_USB_RECORD_REPLAY +  if (testing_mode != sanei_usb_testing_mode_disabled) +    { +      if (initialized == 0) +        { +          if (sanei_usb_testing_init() != SANE_STATUS_GOOD) +            { +              DBG(1, "%s: failed initializing fake USB stack\n", __func__); +              return; +            } +        } + +      if (testing_mode == sanei_usb_testing_mode_replay) +        { +          initialized++; +          return; +        } +    } +#endif +    /* initialize USB with old libusb library */  #ifdef HAVE_LIBUSB_LEGACY    DBG (4, "%s: Looking for libusb devices\n", __func__); @@ -499,7 +1404,12 @@ sanei_usb_init (void)  	}  #ifdef DBG_LEVEL        if (DBG_LEVEL > 4) +#if LIBUSB_API_VERSION >= 0x01000106 +        libusb_set_option (sanei_usb_ctx, LIBUSB_OPTION_LOG_LEVEL, +                           LIBUSB_LOG_LEVEL_INFO); +#else  	libusb_set_debug (sanei_usb_ctx, 3); +#endif /* LIBUSB_API_VERSION */  #endif /* DBG_LEVEL */      }  #endif /* HAVE_LIBUSB */ @@ -533,6 +1443,13 @@ int i;    /* if we reach 0, free allocated resources */    if(initialized==0)      { +#if WITH_USB_RECORD_REPLAY +      if (testing_mode != sanei_usb_testing_mode_disabled) +        { +          sanei_usb_testing_exit(); +        } +#endif // WITH_USB_RECORD_REPLAY +        /* free allocated resources */        DBG (4, "%s: freeing resources\n", __func__);        for (i = 0; i < device_number; i++) @@ -1038,6 +1955,11 @@ sanei_usb_scan_devices (void)        return;      } +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      // device added in sanei_usb_testing_init() +      return; +    }    /* we mark all already detected devices as missing */    /* each scan method will reset this value to 0 (not missing)     * when storing the device */ @@ -1262,6 +2184,77 @@ sanei_usb_set_endpoint (SANE_Int dn, SANE_Int ep_type, SANE_Int ep)      }  } +#if HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS || WITH_USB_RECORD_REPLAY +static const char* sanei_usb_transfer_type_desc(SANE_Int transfer_type) +{ +  switch (transfer_type) +    { +      case USB_ENDPOINT_TYPE_INTERRUPT: return "interrupt"; +      case USB_ENDPOINT_TYPE_BULK: return "bulk"; +      case USB_ENDPOINT_TYPE_ISOCHRONOUS: return "isochronous"; +      case USB_ENDPOINT_TYPE_CONTROL: return "control"; +    } +  return NULL; +} + +// Similar sanei_usb_set_endpoint, but ignors duplicate endpoints +static void sanei_usb_add_endpoint(device_list_type* device, +                                   SANE_Int transfer_type, +                                   SANE_Int ep_address, +                                   SANE_Int ep_direction) +{ +  DBG(5, "%s: direction: %d, address: %d, transfer_type: %d\n", +      __func__, ep_direction, ep_address, transfer_type); + +  SANE_Int* ep_in = NULL; +  SANE_Int* ep_out = NULL; +  const char* transfer_type_msg = sanei_usb_transfer_type_desc(transfer_type); + +  switch (transfer_type) +    { +      case USB_ENDPOINT_TYPE_INTERRUPT: +        ep_in = &device->int_in_ep; +        ep_out = &device->int_out_ep; +        break; +      case USB_ENDPOINT_TYPE_BULK: +        ep_in = &device->bulk_in_ep; +        ep_out = &device->bulk_out_ep; +        break; +      case USB_ENDPOINT_TYPE_ISOCHRONOUS: +        ep_in = &device->iso_in_ep; +        ep_out = &device->iso_out_ep; +        break; +      case USB_ENDPOINT_TYPE_CONTROL: +        ep_in = &device->control_in_ep; +        ep_out = &device->control_out_ep; +        break; +    } + +  DBG(5, "%s: found %s-%s endpoint (address 0x%02x)\n", +      __func__, transfer_type_msg, ep_direction ? "in" : "out", +      ep_address); + +  if (ep_direction) // in +    { +      if (*ep_in) +        DBG(3, "%s: we already have a %s-in endpoint " +             "(address: 0x%02x), ignoring the new one\n", +            __func__, transfer_type_msg, *ep_in); +      else +        *ep_in = ep_address; +    } +  else +    { +      if (*ep_out) +        DBG(3, "%s: we already have a %s-out endpoint " +             "(address: 0x%02x), ignoring the new one\n", +            __func__, transfer_type_msg, *ep_out); +      else +        *ep_out = ep_address; +    } +} +#endif // HAVE_LIBUSB_LEGACY || HAVE_LIBUSB || HAVE_USBCALLS +  SANE_Int  sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type)  { @@ -1294,6 +2287,64 @@ sanei_usb_get_endpoint (SANE_Int dn, SANE_Int ep_type)      }  } +#if WITH_USB_RECORD_REPLAY +static void sanei_usb_record_open(SANE_Int dn) +{ +  xmlNode* e_root = xmlNewNode(NULL, (const xmlChar*) "device_capture"); +  xmlDocSetRootElement(testing_xml_doc, e_root); +  xmlNewProp(e_root, (const xmlChar*)"backend", (const xmlChar*) testing_record_backend); + +  xmlNode* e_description = xmlNewChild(e_root, NULL, (const xmlChar*) "description", NULL); +  sanei_xml_set_hex_attr(e_description, "id_vendor", devices[dn].vendor); +  sanei_xml_set_hex_attr(e_description, "id_product", devices[dn].product); + +  xmlNode* e_configurations = xmlNewChild(e_description, NULL, +                                          (const xmlChar*) "configurations", NULL); +  xmlNode* e_configuration = xmlNewChild(e_configurations, NULL, +                                         (const xmlChar*) "configuration", NULL); +  sanei_xml_set_uint_attr(e_configuration, "number", 1); + +  xmlNode* e_interface = xmlNewChild(e_configuration, NULL, (const xmlChar*) "interface", NULL); +  sanei_xml_set_uint_attr(e_interface, "number", devices[dn].interface_nr); + +  struct endpoint_data_desc { +    const char* transfer_type; +    const char* direction; +    SANE_Int ep_address; +  }; + +  struct endpoint_data_desc endpoints[8] = +  { +    { "BULK", "IN", devices[dn].bulk_in_ep }, +    { "BULK", "OUT", devices[dn].bulk_out_ep }, +    { "ISOCHRONOUS", "IN", devices[dn].iso_in_ep }, +    { "ISOCHRONOUS", "OUT", devices[dn].iso_out_ep }, +    { "INTERRUPT", "IN", devices[dn].int_in_ep }, +    { "INTERRUPT", "OUT", devices[dn].int_out_ep }, +    { "CONTROL", "IN", devices[dn].control_in_ep }, +    { "CONTROL", "OUT", devices[dn].control_out_ep } +  }; + +  for (int i = 0; i < 8; ++i) +    { +      if (endpoints[i].ep_address) +        { +          xmlNode* e_endpoint = xmlNewChild(e_interface, NULL, (const xmlChar*)"endpoint", NULL); +          xmlNewProp(e_endpoint, (const xmlChar*)"transfer_type", +                     (const xmlChar*) endpoints[i].transfer_type); +          sanei_xml_set_uint_attr(e_endpoint, "number", endpoints[i].ep_address & 0x0f); +          xmlNewProp(e_endpoint, (const xmlChar*)"direction", +                     (const xmlChar*) endpoints[i].direction); +          sanei_xml_set_hex_attr(e_endpoint, "address", endpoints[i].ep_address); +        } +    } +  xmlNode* e_transactions = xmlNewChild(e_root, NULL, (const xmlChar*)"transactions", NULL); + +  // add an empty node so that we have something to append to +  testing_append_commands_node =  xmlAddChild(e_transactions, xmlNewText((const xmlChar*)""));; +} +#endif // WITH_USB_RECORD_REPLAY +  SANE_Status  sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)  { @@ -1329,7 +2380,13 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)        return SANE_STATUS_INVAL;      } -  if (devices[devcount].method == sanei_usb_method_libusb) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      DBG (1, "sanei_usb_open: opening fake USB device\n"); +      // the device configuration has been already filled in +      // sanei_usb_testing_init() +    } +  else if (devices[devcount].method == sanei_usb_method_libusb)      {  #ifdef HAVE_LIBUSB_LEGACY        struct usb_device *dev; @@ -1460,132 +2517,12 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)  		      DBG (5, "sanei_usb_open: endpoint nr: %d\n", num);  		      transfer_type =  			endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK; -		      address = -			endpoint-> -			bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;  		      direction =  			endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK; -		      DBG (5, "sanei_usb_open: direction: %d\n", direction); - -		      DBG (5, -			   "sanei_usb_open: address: %d transfertype: %d\n", -			   address, transfer_type); - - -		      /* save the endpoints we need later */ -		      if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT) -			{ -			  DBG (5, -			       "sanei_usb_open: found interrupt-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].int_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a int-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].int_in_ep); -			      else -				devices[devcount].int_in_ep = -				  endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].int_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a int-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].int_out_ep); -			      else -				devices[devcount].int_out_ep = -				  endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == USB_ENDPOINT_TYPE_BULK) -			{ -			  DBG (5, -			       "sanei_usb_open: found bulk-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].bulk_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a bulk-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].bulk_in_ep); -			      else -				devices[devcount].bulk_in_ep = -				  endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].bulk_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a bulk-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].bulk_out_ep); -			      else -				devices[devcount].bulk_out_ep = -				  endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) -			{ -			  DBG (5, -			       "sanei_usb_open: found isochronous-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].iso_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a isochronous-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].iso_in_ep); -			      else -				devices[devcount].iso_in_ep = -				  endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].iso_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a isochronous-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].iso_out_ep); -			      else -				devices[devcount].iso_out_ep = -				  endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == USB_ENDPOINT_TYPE_CONTROL) -			{ -			  DBG (5, -			       "sanei_usb_open: found control-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].control_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a control-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].control_in_ep); -			      else -				devices[devcount].control_in_ep = -				  endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].control_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a control-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].control_out_ep); -			      else -				devices[devcount].control_out_ep = -				  endpoint->bEndpointAddress; -			    } -			} +                      sanei_usb_add_endpoint(&devices[devcount], transfer_type, +                                             endpoint->bEndpointAddress, +                                             direction);  		    }  		}  	    } @@ -1769,124 +2706,39 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)  		  for (num = 0; num < interface->bNumEndpoints; num++)  		    {  		      const struct libusb_endpoint_descriptor *endpoint; -		      int address, direction, transfer_type; +                      int direction, transfer_type, transfer_type_libusb;  		      endpoint = &interface->endpoint[num];  		      DBG (5, "sanei_usb_open: endpoint nr: %d\n", num); -		      transfer_type = endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK; -		      address = endpoint->bEndpointAddress & LIBUSB_ENDPOINT_ADDRESS_MASK; +                      transfer_type_libusb = +                          endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK;  		      direction = endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK; -		      DBG (5, "sanei_usb_open: direction: %d\n", direction); -		      DBG (5, "sanei_usb_open: address: %d transfertype: %d\n", -			   address, transfer_type); - -		      /* save the endpoints we need later */ -		      if (transfer_type == LIBUSB_TRANSFER_TYPE_INTERRUPT) -			{ -			  DBG (5, -			       "sanei_usb_open: found interrupt-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].int_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a int-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].int_in_ep); -			      else -				devices[devcount].int_in_ep = endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].int_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a int-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].int_out_ep); -			      else -				devices[devcount].int_out_ep = endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == LIBUSB_TRANSFER_TYPE_BULK) -			{ -			  DBG (5, -			       "sanei_usb_open: found bulk-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].bulk_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a bulk-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].bulk_in_ep); -			      else -				devices[devcount].bulk_in_ep = endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].bulk_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a bulk-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].bulk_out_ep); -			      else -				devices[devcount].bulk_out_ep = endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) -			{ -			  DBG (5, -			       "sanei_usb_open: found isochronous-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].iso_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a isochronous-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].iso_in_ep); -			      else -				devices[devcount].iso_in_ep = endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].iso_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a isochronous-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].iso_out_ep); -			      else -				devices[devcount].iso_out_ep = endpoint->bEndpointAddress; -			    } -			} -		      else if (transfer_type == LIBUSB_TRANSFER_TYPE_CONTROL) -			{ -			  DBG (5, -			       "sanei_usb_open: found control-%s endpoint (address 0x%02x)\n", -			       direction ? "in" : "out", address); -			  if (direction)	/* in */ -			    { -			      if (devices[devcount].control_in_ep) -				DBG (3, -				     "sanei_usb_open: we already have a control-in endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].control_in_ep); -			      else -				devices[devcount].control_in_ep = endpoint->bEndpointAddress; -			    } -			  else -			    { -			      if (devices[devcount].control_out_ep) -				DBG (3, -				     "sanei_usb_open: we already have a control-out endpoint " -				     "(address: 0x%02x), ignoring the new one\n", -				     devices[devcount].control_out_ep); -			      else -				devices[devcount].control_out_ep = endpoint->bEndpointAddress; -			    } -			} +                      // don't rely on LIBUSB_TRANSFER_TYPE_* mapping to +                      // USB_ENDPOINT_TYPE_* even though they'll most likely be +                      // the same +                      switch (transfer_type_libusb) +                        { +                          case LIBUSB_TRANSFER_TYPE_INTERRUPT: +                            transfer_type = USB_ENDPOINT_TYPE_INTERRUPT; +                            break; +                          case LIBUSB_TRANSFER_TYPE_BULK: +                            transfer_type = USB_ENDPOINT_TYPE_BULK; +                            break; +                          case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: +                            transfer_type = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; +                            break; +                          case LIBUSB_TRANSFER_TYPE_CONTROL: +                            transfer_type = USB_ENDPOINT_TYPE_CONTROL; +                            break; + +                        } + +                      sanei_usb_add_endpoint(&devices[devcount], +                                             transfer_type, +                                             endpoint->bEndpointAddress, +                                             direction);  		    }  		}  	    } @@ -2016,62 +2868,21 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)                break;              case USB_DT_ENDPOINT:  	      endpoint = (struct usb_endpoint_descriptor*)pDescHead; -              address = endpoint->bEndpointAddress;  	      direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;  	      transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK; -	      /* save the endpoints we need later */ -	      if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT) -	      { -   	       DBG (5, "sanei_usb_open: found interupt-%s endpoint (address %2x)\n", -  	            direction ? "in" : "out", address); -	       if (direction)	/* in */ -	       { -	         if (devices[devcount].int_in_ep) -		   DBG (3, "sanei_usb_open: we already have a int-in endpoint " -		        "(address: %d), ignoring the new one\n", -		        devices[devcount].int_in_ep); -	         else -		   devices[devcount].int_in_ep = endpoint->bEndpointAddress; -	       } -	       else -	         if (devices[devcount].int_out_ep) -		   DBG (3, "sanei_usb_open: we already have a int-out endpoint " -		        "(address: %d), ignoring the new one\n", -		        devices[devcount].int_out_ep); -	         else -		   devices[devcount].int_out_ep = endpoint->bEndpointAddress; -	     } -	     else if (transfer_type == USB_ENDPOINT_TYPE_BULK) -	     { -	       DBG (5, "sanei_usb_open: found bulk-%s endpoint (address %2x)\n", -	            direction ? "in" : "out", address); -	       if (direction)	/* in */ -	         { -		   if (devices[devcount].bulk_in_ep) -		     DBG (3, "sanei_usb_open: we already have a bulk-in endpoint " -		          "(address: %d), ignoring the new one\n", -		          devices[devcount].bulk_in_ep); -		   else -		     devices[devcount].bulk_in_ep = endpoint->bEndpointAddress; -	         } -	       else -	         { -	           if (devices[devcount].bulk_out_ep) -		     DBG (3, "sanei_usb_open: we already have a bulk-out endpoint " -		          "(address: %d), ignoring the new one\n", -		          devices[devcount].bulk_out_ep); -	           else -		     devices[devcount].bulk_out_ep = endpoint->bEndpointAddress; -	         } -	       } + +              if (transfer_type == USB_ENDPOINT_TYPE_INTERRUPT || +                  transfer_type == USB_ENDPOINT_TYPE_BULK) +                { +                  sanei_usb_add_endpoint(&devices[devcount], transfer_type, +                                         endpoint->bEndpointAddress, direction); +                }  	     /* ignore currently unsupported endpoints */  	     else {  	         DBG (5, "sanei_usb_open: ignoring %s-%s endpoint "  		      "(address: %d)\n", -		      transfer_type == USB_ENDPOINT_TYPE_CONTROL ? "control" : -		      transfer_type == USB_ENDPOINT_TYPE_ISOCHRONOUS -		      ? "isochronous" : "interrupt", -		      direction ? "in" : "out", address); +                      sanei_usb_transfer_type_desc(transfer_type), +                      direction ? "in" : "out", address);  	         continue;  	          }            break; @@ -2090,6 +2901,16 @@ sanei_usb_open (SANE_String_Const devname, SANE_Int * dn)        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      sanei_usb_record_open(devcount); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +    devices[devcount].open = SANE_TRUE;    *dn = devcount;    DBG (3, "sanei_usb_open: opened usb device `%s' (*dn=%d)\n", @@ -2123,7 +2944,11 @@ sanei_usb_close (SANE_Int dn)  	   dn);        return;      } -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      DBG (1, "sanei_usb_close: closing fake USB device\n"); +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      close (devices[dn].fd);    else if (devices[dn].method == sanei_usb_method_usbcalls)      { @@ -2176,6 +3001,9 @@ sanei_usb_close (SANE_Int dn)  void  sanei_usb_set_timeout (SANE_Int __sane_unused__ timeout)  { +  if (testing_mode == sanei_usb_testing_mode_replay) +    return; +  #if defined(HAVE_LIBUSB_LEGACY) || defined(HAVE_LIBUSB)    libusb_timeout = timeout;  #else @@ -2203,6 +3031,9 @@ sanei_usb_clear_halt (SANE_Int dn)        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_replay) +    return SANE_STATUS_GOOD; +  #ifdef HAVE_LIBUSB_LEGACY    int ret; @@ -2260,6 +3091,9 @@ sanei_usb_clear_halt (SANE_Int dn)  SANE_Status  sanei_usb_reset (SANE_Int __sane_unused__ dn)  { +  if (testing_mode == sanei_usb_testing_mode_replay) +    return SANE_STATUS_GOOD; +  #ifdef HAVE_LIBUSB_LEGACY    int ret; @@ -2285,6 +3119,160 @@ sanei_usb_reset (SANE_Int __sane_unused__ dn)    return SANE_STATUS_GOOD;  } +#if WITH_USB_RECORD_REPLAY +// returns non-negative value on success, -1 on failure +static int sanei_usb_replay_next_read_bulk_packet_size(SANE_Int dn) +{ +  xmlNode* node = sanei_xml_peek_next_tx_node(); +  if (node == NULL) +    return -1; + +  if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) +    { +      return -1; +    } + +  if (!sanei_usb_attr_is(node, "direction", "IN")) +    return -1; +  if (!sanei_usb_attr_is_uint(node, "endpoint_number", +                              devices[dn].bulk_in_ep & 0x0f)) +    return -1; + +  size_t got_size = 0; +  char* got_data = sanei_xml_get_hex_data(node, &got_size); +  free(got_data); +  return got_size; +} + +static void sanei_usb_record_read_bulk(xmlNode* node, SANE_Int dn, +                                       SANE_Byte* buffer, +                                       size_t size, ssize_t read_size) +{ +  int node_was_null = node == NULL; +  if (node_was_null) +    node = testing_append_commands_node; + +  xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx"); +  sanei_xml_command_common_props(e_tx, devices[dn].bulk_in_ep & 0x0f, "IN"); + +  if (buffer == NULL) +    { +      const int buf_size = 128; +      char buf[buf_size]; +      snprintf(buf, buf_size, "(unknown read of allowed size %ld)", size); +      xmlNode* e_content = xmlNewText((const xmlChar*)buf); +      xmlAddChild(e_tx, e_content); +    } +  else +    { +      if (read_size >= 0) +        { +          sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size); +        } +      else +        { +          xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout"); +        } +    } + +  node = sanei_xml_append_command(node, node_was_null, e_tx); + +  if (node_was_null) +    testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_read_bulk(xmlNode* node, SANE_Int dn, +                                               SANE_Byte* buffer, +                                               size_t size, size_t read_size) +{ +  if (!testing_development_mode) +    return; +  testing_known_commands_input_failed = 1; +  testing_last_known_seq--; +  sanei_usb_record_read_bulk(node, dn, buffer, size, read_size); +  xmlUnlinkNode(node); +  xmlFreeNode(node); +} + +static int sanei_usb_replay_read_bulk(SANE_Int dn, SANE_Byte* buffer, +                                      size_t size) +{ +  // libusb may potentially combine multiple IN packets into a single transfer. +  // We recontruct that by looking into the next packet. If it can be +  // included into the current transfer without +  size_t wanted_size = size; +  size_t total_got_size = 0; +  while (wanted_size > 0) +    { +      if (testing_known_commands_input_failed) +        return -1; + +      xmlNode* node = sanei_xml_get_next_tx_node(); +      if (node == NULL) +        { +          FAIL_TEST(__func__, "no more transactions\n"); +          return -1; +        } + +      if (sanei_xml_is_known_commands_end(node)) +        { +          sanei_usb_record_read_bulk(NULL, dn, NULL, 0, size); +          testing_known_commands_input_failed = 1; +          return -1; +        } + +      sanei_xml_record_seq(node); +      sanei_xml_break_if_needed(node); + +      if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) +        { +          FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                       (const char*) node->name); +          sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); +          return -1; +        } + +      if (!sanei_usb_check_attr(node, "direction", "IN", __func__)) +        { +          sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); +          return -1; +        } +      if (!sanei_usb_check_attr_uint(node, "endpoint_number", +                                     devices[dn].bulk_in_ep & 0x0f, +                                     __func__)) +        { +          sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); +          return -1; +        } + +      size_t got_size = 0; +      char* got_data = sanei_xml_get_hex_data(node, &got_size); + +      if (got_size > wanted_size) +        { +          FAIL_TEST_TX(__func__, node, +                       "got more data than wanted (%lu vs %lu)\n", +                       got_size, wanted_size); +          free(got_data); +          sanei_usb_record_replace_read_bulk(node, dn, NULL, 0, wanted_size); +          return -1; +        } + +      memcpy(buffer + total_got_size, got_data, got_size); +      free(got_data); +      total_got_size += got_size; +      wanted_size -= got_size; + +      int next_size = sanei_usb_replay_next_read_bulk_packet_size(dn); +      if (next_size < 0) +        return total_got_size; +      if ((size_t) next_size > wanted_size) +        return total_got_size; +    } +  return total_got_size; +} +#endif // WITH_USB_RECORD_REPLAY +  SANE_Status  sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)  { @@ -2304,7 +3292,16 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)    DBG (5, "sanei_usb_read_bulk: trying to read %lu bytes\n",         (unsigned long) *size); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +#if WITH_USB_RECORD_REPLAY +      read_size = sanei_usb_replay_read_bulk(dn, buffer, *size); +#else +      DBG(1, "%s: USB record-replay mode support missing\n", __func__); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {        read_size = read (devices[dn].fd, buffer, *size); @@ -2344,8 +3341,8 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)  	  if (ret < 0)  	    { -	      DBG (1, "sanei_usb_read_bulk: read failed: %s\n", -		   sanei_libusb_strerror (ret)); +              DBG (1, "sanei_usb_read_bulk: read failed (still got %d bytes): %s\n", +                   rsize, sanei_libusb_strerror (ret));  	      read_size = -1;  	    } @@ -2372,9 +3369,10 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)  #ifdef HAVE_USBCALLS      int rc;      char* buffer_ptr = (char*) buffer; -    while (*size) +    size_t requested_size = *size; +    while (requested_size)      { -      ULONG ulToRead = (*size>MAX_RW)?MAX_RW:*size; +      ULONG ulToRead = (requested_size>MAX_RW)?MAX_RW:requested_size;        ULONG ulNum = ulToRead;        DBG (5, "Entered usbcalls UsbBulkRead with dn = %d\n",dn);        DBG (5, "Entered usbcalls UsbBulkRead with dh = %p\n",dh); @@ -2392,7 +3390,7 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)            return SANE_STATUS_INVAL;        }        if (rc || (ulNum!=ulToRead)) return SANE_STATUS_INVAL; -      *size -=ulToRead; +      requested_size -=ulToRead;        buffer_ptr += ulToRead;        read_size += ulToRead;      } @@ -2410,8 +3408,22 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      sanei_usb_record_read_bulk(NULL, dn, buffer, *size, read_size); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +    if (read_size < 0)      { +      *size = 0; +      if (testing_mode != sanei_usb_testing_mode_disabled) +        return SANE_STATUS_IO_ERROR; +  #ifdef HAVE_LIBUSB_LEGACY        if (devices[dn].method == sanei_usb_method_libusb)  	usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_in_ep); @@ -2419,7 +3431,6 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)        if (devices[dn].method == sanei_usb_method_libusb)  	libusb_clear_halt (devices[dn].lu_handle, devices[dn].bulk_in_ep);  #endif -      *size = 0;        return SANE_STATUS_IO_ERROR;      }    if (read_size == 0) @@ -2437,6 +3448,165 @@ sanei_usb_read_bulk (SANE_Int dn, SANE_Byte * buffer, size_t * size)    return SANE_STATUS_GOOD;  } +#if WITH_USB_RECORD_REPLAY +static int sanei_usb_record_write_bulk(xmlNode* node, SANE_Int dn, +                                       const SANE_Byte* buffer, +                                       size_t size, size_t write_size) +{ +  int node_was_null = node == NULL; +  if (node_was_null) +    node = testing_append_commands_node; + +  xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"bulk_tx"); +  sanei_xml_command_common_props(e_tx, devices[dn].bulk_out_ep & 0x0f, "OUT"); +  sanei_xml_set_hex_data(e_tx, (const char*)buffer, size); +  // FIXME: output write_size + +  node = sanei_xml_append_command(node, node_was_null, e_tx); + +  if (node_was_null) +    testing_append_commands_node = node; +  return write_size; +} + +static void sanei_usb_record_replace_write_bulk(xmlNode* node, SANE_Int dn, +                                                const SANE_Byte* buffer, +                                                size_t size, size_t write_size) +{ +  if (!testing_development_mode) +    return; +  testing_last_known_seq--; +  sanei_usb_record_write_bulk(node, dn, buffer, size, write_size); +  xmlUnlinkNode(node); +  xmlFreeNode(node); +} + +// returns non-negative value on success, -1 on failure +static int sanei_usb_replay_next_write_bulk_packet_size(SANE_Int dn) +{ +  xmlNode* node = sanei_xml_peek_next_tx_node(); +  if (node == NULL) +    return -1; + +  if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) +    { +      return -1; +    } + +  if (!sanei_usb_attr_is(node, "direction", "OUT")) +    return -1; +  if (!sanei_usb_attr_is_uint(node, "endpoint_number", +                              devices[dn].bulk_out_ep & 0x0f)) +    return -1; + +  size_t got_size = 0; +  char* got_data = sanei_xml_get_hex_data(node, &got_size); +  free(got_data); +  return got_size; +} + +static int sanei_usb_replay_write_bulk(SANE_Int dn, const SANE_Byte* buffer, +                                       size_t size) +{ +  size_t wanted_size = size; +  size_t total_wrote_size = 0; +  while (wanted_size > 0) +    { +      if (testing_known_commands_input_failed) +        return -1; + +      xmlNode* node = sanei_xml_get_next_tx_node(); +      if (node == NULL) +        { +          FAIL_TEST(__func__, "no more transactions\n"); +          return -1; +        } + +      if (sanei_xml_is_known_commands_end(node)) +        { +          sanei_usb_record_write_bulk(NULL, dn, buffer, size, size); +          return size; +        } + +      sanei_xml_record_seq(node); +      sanei_xml_break_if_needed(node); + +      if (xmlStrcmp(node->name, (const xmlChar*)"bulk_tx") != 0) +        { +          FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                       (const char*) node->name); +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); +          return -1; +        } + +      if (!sanei_usb_check_attr(node, "direction", "OUT", __func__)) +        { +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); +          return -1; +        } +      if (!sanei_usb_check_attr_uint(node, "endpoint_number", +                                     devices[dn].bulk_out_ep & 0x0f, +                                     __func__)) +        { +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); +          return -1; +        } + +      size_t wrote_size = 0; +      char* wrote_data = sanei_xml_get_hex_data(node, &wrote_size); + +      if (wrote_size > wanted_size) +        { +          FAIL_TEST_TX(__func__, node, +                       "wrote more data than wanted (%lu vs %lu)\n", +                       wrote_size, wanted_size); +          if (!testing_development_mode) +            { +              free(wrote_data); +              return -1; +            } +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, size); +          wrote_size = size; +        } +      else if (!sanei_usb_check_data_equal(node, +                                           ((const char*) buffer) + +                                              total_wrote_size, +                                           wrote_size, +                                           wrote_data, wrote_size, +                                           __func__)) +        { +          if (!testing_development_mode) +            { +              free(wrote_data); +              return -1; +            } +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, +                                              size); +          wrote_size = size; +        } + +      free(wrote_data); +      if (wrote_size < wanted_size && +          sanei_usb_replay_next_write_bulk_packet_size(dn) < 0) +        { +          FAIL_TEST_TX(__func__, node, +                       "wrote less data than wanted (%lu vs %lu)\n", +                       wrote_size, wanted_size); +          if (!testing_development_mode) +            { +              return -1; +            } +          sanei_usb_record_replace_write_bulk(node, dn, buffer, size, +                                              size); +          wrote_size = size; +        } +      total_wrote_size += wrote_size; +      wanted_size -= wrote_size; +    } +  return total_wrote_size; +} +#endif +  SANE_Status  sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)  { @@ -2458,7 +3628,16 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)    if (debug_level > 10)      print_buffer (buffer, *size); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +#if WITH_USB_RECORD_REPLAY +      write_size = sanei_usb_replay_write_bulk(dn, buffer, *size); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {        write_size = write (devices[dn].fd, buffer, *size); @@ -2529,11 +3708,12 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)      DBG (5, "Entered usbcalls UsbBulkWrite with bulk_out_ep = 0x%02x\n",devices[dn].bulk_out_ep);      DBG (5, "Entered usbcalls UsbBulkWrite with interface_nr = %d\n",devices[dn].interface_nr);      DBG (5, "Entered usbcalls UsbBulkWrite with usbcalls_timeout = %d\n",usbcalls_timeout); -    while (*size) +    size_t requested_size = *size; +    while (requested_size)      { -      ULONG ulToWrite = (*size>MAX_RW)?MAX_RW:*size; +      ULONG ulToWrite = (requested_size>MAX_RW)?MAX_RW:requested_size; -      DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) *size,ulToWrite); +      DBG (5, "size requested to write = %lu, ulToWrite = %lu\n",(unsigned long) requested_size,ulToWrite);        if (devices[dn].bulk_out_ep){          rc = UsbBulkWrite (dh, devices[dn].bulk_out_ep, devices[dn].interface_nr,                                 ulToWrite, (char*) buffer, usbcalls_timeout); @@ -2545,10 +3725,10 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)            return SANE_STATUS_INVAL;        }        if (rc) return SANE_STATUS_INVAL; -      *size -=ulToWrite; +      requested_size -=ulToWrite;        buffer += ulToWrite;        write_size += ulToWrite; -      DBG (5, "size = %d, write_size = %d\n",*size, write_size); +      DBG (5, "size = %d, write_size = %d\n", requested_size, write_size);      }  #else /* not HAVE_USBCALLS */      { @@ -2564,9 +3744,22 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      sanei_usb_record_write_bulk(NULL, dn, buffer, *size, write_size); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +    if (write_size < 0)      {        *size = 0; +      if (testing_mode != sanei_usb_testing_mode_disabled) +        return SANE_STATUS_IO_ERROR; +  #ifdef HAVE_LIBUSB_LEGACY        if (devices[dn].method == sanei_usb_method_libusb)  	usb_clear_halt (devices[dn].libusb_handle, devices[dn].bulk_out_ep); @@ -2582,6 +3775,161 @@ sanei_usb_write_bulk (SANE_Int dn, const SANE_Byte * buffer, size_t * size)    return SANE_STATUS_GOOD;  } +#if WITH_USB_RECORD_REPLAY +static void +sanei_usb_record_control_msg(xmlNode* node, +                             SANE_Int dn, SANE_Int rtype, SANE_Int req, +                             SANE_Int value, SANE_Int index, SANE_Int len, +                             const SANE_Byte* data) +{ +  (void) dn; + +  int node_was_null = node == NULL; +  if (node_was_null) +    node = testing_append_commands_node; + +  xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"control_tx"); + +  int direction_is_in = (rtype & 0x80) == 0x80; +  sanei_xml_command_common_props(e_tx, rtype & 0x1f, +                                 direction_is_in ? "IN" : "OUT"); +  sanei_xml_set_hex_attr(e_tx, "bmRequestType", rtype); +  sanei_xml_set_hex_attr(e_tx, "bRequest", req); +  sanei_xml_set_hex_attr(e_tx, "wValue", value); +  sanei_xml_set_hex_attr(e_tx, "wIndex", index); +  sanei_xml_set_hex_attr(e_tx, "wLength", len); + +  if (direction_is_in && data == NULL) +    { +      const int buf_size = 128; +      char buf[buf_size]; +      snprintf(buf, buf_size, "(unknown read of size %d)", len); +      xmlNode* e_content = xmlNewText((const xmlChar*)buf); +      xmlAddChild(e_tx, e_content); +    } +  else +    { +      sanei_xml_set_hex_data(e_tx, (const char*)data, len); +    } + +  node = sanei_xml_append_command(node, node_was_null, e_tx); + +  if (node_was_null) +    testing_append_commands_node = node; +} + + +static SANE_Status +sanei_usb_record_replace_control_msg(xmlNode* node, +                                     SANE_Int dn, SANE_Int rtype, SANE_Int req, +                                     SANE_Int value, SANE_Int index, SANE_Int len, +                                     const SANE_Byte* data) +{ +  if (!testing_development_mode) +    return SANE_STATUS_IO_ERROR; + +  SANE_Status ret = SANE_STATUS_GOOD; +  int direction_is_in = (rtype & 0x80) == 0x80; +  if (direction_is_in) +    { +      testing_known_commands_input_failed = 1; +      ret = SANE_STATUS_IO_ERROR; +    } + +  testing_last_known_seq--; +  sanei_usb_record_control_msg(node, dn, rtype, req, value, index, len, data); +  xmlUnlinkNode(node); +  xmlFreeNode(node); +  return ret; +} + +static SANE_Status +sanei_usb_replay_control_msg(SANE_Int dn, SANE_Int rtype, SANE_Int req, +                             SANE_Int value, SANE_Int index, SANE_Int len, +                             SANE_Byte* data) +{ +  (void) dn; + +  if (testing_known_commands_input_failed) +    return -1; + +  xmlNode* node = sanei_xml_get_next_tx_node(); +  if (node == NULL) +    { +      FAIL_TEST(__func__, "no more transactions\n"); +      return SANE_STATUS_IO_ERROR; +    } + +  int direction_is_in = (rtype & 0x80) == 0x80; +  SANE_Byte* rdata = direction_is_in ? NULL : data; + +  if (sanei_xml_is_known_commands_end(node)) +    { +      sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len, +                                   rdata); +      if (direction_is_in) +        { +          testing_known_commands_input_failed = 1; +          return SANE_STATUS_IO_ERROR; +        } +      return SANE_STATUS_GOOD; +    } + +  sanei_xml_record_seq(node); +  sanei_xml_break_if_needed(node); + +  if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) +    { +      FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                   (const char*) node->name); +      return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value, +                                                  index, len, rdata); +    } + +  if (!sanei_usb_check_attr(node, "direction", direction_is_in ? "IN" : "OUT", +                            __func__) || +      !sanei_usb_check_attr_uint(node, "bmRequestType", rtype, __func__) || +      !sanei_usb_check_attr_uint(node, "bRequest", req, __func__) || +      !sanei_usb_check_attr_uint(node, "wValue", value, __func__) || +      !sanei_usb_check_attr_uint(node, "wIndex", index, __func__) || +      !sanei_usb_check_attr_uint(node, "wLength", len, __func__)) +    { +      return sanei_usb_record_replace_control_msg(node, dn, rtype, req, value, +                                                  index, len, rdata); +    } + +  size_t tx_data_size = 0; +  char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size); + +  if (direction_is_in) +    { +      if (tx_data_size != (size_t)len) +        { +          FAIL_TEST_TX(__func__, node, +                       "got different amount of data than wanted (%lu vs %lu)\n", +                       tx_data_size, (size_t)len); +          free(tx_data); +          return sanei_usb_record_replace_control_msg(node, dn, rtype, req, +                                                      value, index, len, rdata); +        } +      memcpy(data, tx_data, tx_data_size); +    } +  else +    { +      if (!sanei_usb_check_data_equal(node, +                                      (const char*)data, len, +                                      tx_data, tx_data_size, __func__)) +        { +          free(tx_data); +          return sanei_usb_record_replace_control_msg(node, dn, rtype, req, +                                                      value, index, len, rdata); +        } +    } +  free(tx_data); +  return SANE_STATUS_GOOD; +} +#endif +  SANE_Status  sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  		       SANE_Int value, SANE_Int index, SANE_Int len, @@ -2599,6 +3947,16 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,    if (!(rtype & 0x80) && debug_level > 10)      print_buffer (data, len); +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +#if WITH_USB_RECORD_REPLAY +      return sanei_usb_replay_control_msg(dn, rtype, req, value, index, len, +                                          data); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    }    if (devices[dn].method == sanei_usb_method_scanner_driver)      {  #if defined(__linux__) @@ -2619,7 +3977,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	}        if ((rtype & 0x80) && debug_level > 10)  	print_buffer (data, len); -      return SANE_STATUS_GOOD;  #elif defined(__BEOS__)        struct usb_scanner_ioctl_ctrlmsg c; @@ -2638,8 +3995,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	}  	if ((rtype & 0x80) && debug_level > 10)  		print_buffer (data, len); - -	return SANE_STATUS_GOOD;  #else /* not __linux__ */        DBG (5, "sanei_usb_control_msg: not supported on this OS\n");        return SANE_STATUS_UNSUPPORTED; @@ -2661,7 +4016,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	}        if ((rtype & 0x80) && debug_level > 10)  	print_buffer (data, len); -      return SANE_STATUS_GOOD;      }  #elif defined(HAVE_LIBUSB)      { @@ -2678,7 +4032,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	}        if ((rtype & 0x80) && debug_level > 10)  	print_buffer (data, len); -      return SANE_STATUS_GOOD;      }  #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB*/      { @@ -2702,7 +4055,6 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	}        if ((rtype & 0x80) && debug_level > 10)  	print_buffer (data, len); -      return SANE_STATUS_GOOD;  #else /* not HAVE_USBCALLS */      {        DBG (1, "sanei_usb_control_msg: usbcalls support missing\n"); @@ -2716,8 +4068,141 @@ sanei_usb_control_msg (SANE_Int dn, SANE_Int rtype, SANE_Int req,  	   devices[dn].method);        return SANE_STATUS_UNSUPPORTED;      } + +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      // TODO: record in the error code path too +      sanei_usb_record_control_msg(NULL, dn, rtype, req, value, index, len, +                                   data); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +  return SANE_STATUS_GOOD; +} + +#if WITH_USB_RECORD_REPLAY +static void sanei_usb_record_read_int(xmlNode* node, +                                      SANE_Int dn, SANE_Byte* buffer, +                                      size_t size, ssize_t read_size) +{ +  (void) size; + +  int node_was_null = node == NULL; +  if (node_was_null) +    node = testing_append_commands_node; + +  xmlNode* e_tx = xmlNewNode(NULL, (const xmlChar*)"interrupt_tx"); + +  sanei_xml_command_common_props(e_tx, devices[dn].int_in_ep & 0x0f, "IN"); + +  if (buffer == NULL) +    { +      const int buf_size = 128; +      char buf[buf_size]; +      snprintf(buf, buf_size, "(unknown read of wanted size %ld)", read_size); +      xmlNode* e_content = xmlNewText((const xmlChar*)buf); +      xmlAddChild(e_tx, e_content); +    } +  else +    { +      if (read_size >= 0) +        { +          sanei_xml_set_hex_data(e_tx, (const char*)buffer, read_size); +        } +      else +        { +          xmlNewProp(e_tx, (const xmlChar*)"error", (const xmlChar*)"timeout"); +        } +    } + +  node = sanei_xml_append_command(node, node_was_null, e_tx); + +  if (node_was_null) +    testing_append_commands_node = node; +} + +static void sanei_usb_record_replace_read_int(xmlNode* node, +                                              SANE_Int dn, SANE_Byte* buffer, +                                              size_t size, size_t read_size) +{ +  if (!testing_development_mode) +    return; +  testing_known_commands_input_failed = 1; +  testing_last_known_seq--; +  sanei_usb_record_read_int(node, dn, buffer, size, read_size); +  xmlUnlinkNode(node); +  xmlFreeNode(node);  } +static int sanei_usb_replay_read_int(SANE_Int dn, SANE_Byte* buffer, +                                     size_t size) +{ +  if (testing_known_commands_input_failed) +    return -1; + +  size_t wanted_size = size; + +  xmlNode* node = sanei_xml_get_next_tx_node(); +  if (node == NULL) +    { +      FAIL_TEST(__func__, "no more transactions\n"); +      return -1; +    } + +  if (sanei_xml_is_known_commands_end(node)) +    { +      sanei_usb_record_read_int(NULL, dn, NULL, 0, size); +      testing_known_commands_input_failed = 1; +      return -1; +    } + +  sanei_xml_record_seq(node); +  sanei_xml_break_if_needed(node); + +  if (xmlStrcmp(node->name, (const xmlChar*)"interrupt_tx") != 0) +    { +      FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                   (const char*) node->name); +      sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); +      return -1; +    } + +  if (!sanei_usb_check_attr(node, "direction", "IN", __func__)) +    { +      sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); +      return -1; +    } + +  if (!sanei_usb_check_attr_uint(node, "endpoint_number", +                                 devices[dn].int_in_ep & 0x0f, +                                 __func__)) +    { +      sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); +      return -1; +    } + +  size_t tx_data_size = 0; +  char* tx_data = sanei_xml_get_hex_data(node, &tx_data_size); + +  if (tx_data_size > wanted_size) +    { +      FAIL_TEST_TX(__func__, node, +                   "got more data than wanted (%lu vs %lu)\n", +                   tx_data_size, wanted_size); +      sanei_usb_record_replace_read_int(node, dn, NULL, 0, size); +      free(tx_data); +      return -1; +    } + +  memcpy((char*) buffer, tx_data, tx_data_size); +  free(tx_data); +  return tx_data_size; +} +#endif // WITH_USB_RECORD_REPLAY +  SANE_Status  sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)  { @@ -2740,7 +4225,16 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)    DBG (5, "sanei_usb_read_int: trying to read %lu bytes\n",         (unsigned long) *size); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +#if WITH_USB_RECORD_REPLAY +      read_size = sanei_usb_replay_read_int(dn, buffer, *size); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {        DBG (1, "sanei_usb_read_int: access method %d not implemented\n",  	   devices[dn].method); @@ -2836,8 +4330,22 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      sanei_usb_record_read_int(NULL, dn, buffer, *size, read_size); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +    if (read_size < 0)      { +      *size = 0; +      if (testing_mode != sanei_usb_testing_mode_disabled) +        return SANE_STATUS_IO_ERROR; +  #ifdef HAVE_LIBUSB_LEGACY        if (devices[dn].method == sanei_usb_method_libusb)          if (stalled) @@ -2847,7 +4355,6 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)          if (stalled)  	  libusb_clear_halt (devices[dn].lu_handle, devices[dn].int_in_ep);  #endif -      *size = 0;        return SANE_STATUS_IO_ERROR;      }    if (read_size == 0) @@ -2865,6 +4372,58 @@ sanei_usb_read_int (SANE_Int dn, SANE_Byte * buffer, size_t * size)    return SANE_STATUS_GOOD;  } +#if WITH_USB_RECORD_REPLAY +static SANE_Status sanei_usb_replay_set_configuration(SANE_Int dn, +                                                      SANE_Int configuration) +{ +  (void) dn; + +  xmlNode* node = sanei_xml_get_next_tx_node(); +  if (node == NULL) +    { +      FAIL_TEST(__func__, "no more transactions\n"); +      return SANE_STATUS_IO_ERROR; +    } + +  sanei_xml_record_seq(node); +  sanei_xml_break_if_needed(node); + +  if (xmlStrcmp(node->name, (const xmlChar*)"control_tx") != 0) +    { +      FAIL_TEST_TX(__func__, node, "unexpected transaction type %s\n", +                   (const char*) node->name); +      return SANE_STATUS_IO_ERROR; +    } + +  if (!sanei_usb_check_attr(node, "direction", "OUT", __func__)) +    return SANE_STATUS_IO_ERROR; + +  if (!sanei_usb_check_attr_uint(node, "bmRequestType", 0, __func__)) +    return SANE_STATUS_IO_ERROR; + +  if (!sanei_usb_check_attr_uint(node, "bRequest", 9, __func__)) +    return SANE_STATUS_IO_ERROR; + +  if (!sanei_usb_check_attr_uint(node, "wValue", configuration, __func__)) +    return SANE_STATUS_IO_ERROR; + +  if (!sanei_usb_check_attr_uint(node, "wIndex", 0, __func__)) +    return SANE_STATUS_IO_ERROR; + +  if (!sanei_usb_check_attr_uint(node, "wLength", 0, __func__)) +    return SANE_STATUS_IO_ERROR; + +  return SANE_STATUS_GOOD; +} + +static void sanei_usb_record_set_configuration(SANE_Int dn, +                                               SANE_Int configuration) +{ +  (void) dn; (void) configuration; +  // TODO +} +#endif // WITH_USB_RECORD_REPLAY +  SANE_Status  sanei_usb_set_configuration (SANE_Int dn, SANE_Int configuration)  { @@ -2878,7 +4437,26 @@ sanei_usb_set_configuration (SANE_Int dn, SANE_Int configuration)    DBG (5, "sanei_usb_set_configuration: configuration = %d\n", configuration); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_record) +    { +#if WITH_USB_RECORD_REPLAY +      sanei_usb_record_set_configuration(dn, configuration); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } + +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +#if WITH_USB_RECORD_REPLAY +      return sanei_usb_replay_set_configuration(dn, configuration); +#else +      DBG (1, "USB record-replay mode support is missing\n"); +      return SANE_STATUS_UNSUPPORTED; +#endif +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {  #if defined(__linux__)        return SANE_STATUS_GOOD; @@ -2948,7 +4526,11 @@ sanei_usb_claim_interface (SANE_Int dn, SANE_Int interface_number)    DBG (5, "sanei_usb_claim_interface: interface_number = %d\n", interface_number); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      return SANE_STATUS_GOOD; +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {  #if defined(__linux__)        return SANE_STATUS_GOOD; @@ -3015,7 +4597,11 @@ sanei_usb_release_interface (SANE_Int dn, SANE_Int interface_number)      }    DBG (5, "sanei_usb_release_interface: interface_number = %d\n", interface_number); -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      return SANE_STATUS_GOOD; +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {  #if defined(__linux__)        return SANE_STATUS_GOOD; @@ -3081,7 +4667,11 @@ sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate)    devices[dn].alt_setting = alternate; -  if (devices[dn].method == sanei_usb_method_scanner_driver) +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      return SANE_STATUS_GOOD; +    } +  else if (devices[dn].method == sanei_usb_method_scanner_driver)      {  #if defined(__linux__)        return SANE_STATUS_GOOD; @@ -3133,6 +4723,25 @@ sanei_usb_set_altinterface (SANE_Int dn, SANE_Int alternate)      }  } +static SANE_Status +sanei_usb_replay_get_descriptor(SANE_Int dn, +                                struct sanei_usb_dev_descriptor *desc) +{ +  (void) dn; +  (void) desc; +  return SANE_STATUS_UNSUPPORTED; +  // ZZTODO +} + +static void +sanei_usb_record_get_descriptor(SANE_Int dn, +                                struct sanei_usb_dev_descriptor *desc) +{ +  (void) dn; +  (void) desc; +  // ZZTODO +} +  extern SANE_Status  sanei_usb_get_descriptor( SANE_Int dn,                            struct sanei_usb_dev_descriptor __sane_unused__ @@ -3146,6 +4755,11 @@ sanei_usb_get_descriptor( SANE_Int dn,        return SANE_STATUS_INVAL;      } +  if (testing_mode == sanei_usb_testing_mode_replay) +    { +      return sanei_usb_replay_get_descriptor(dn, desc); +    } +    DBG (5, "sanei_usb_get_descriptor\n");  #ifdef HAVE_LIBUSB_LEGACY      { @@ -3160,7 +4774,6 @@ sanei_usb_get_descriptor( SANE_Int dn,  	  desc->dev_sub_class   = usb_descr->bDeviceSubClass;  	  desc->dev_protocol    = usb_descr->bDeviceProtocol;  	  desc->max_packet_size = usb_descr->bMaxPacketSize0; -	  return SANE_STATUS_GOOD;      }  #elif defined(HAVE_LIBUSB)      { @@ -3185,7 +4798,6 @@ sanei_usb_get_descriptor( SANE_Int dn,        desc->dev_sub_class   = lu_desc.bDeviceSubClass;        desc->dev_protocol    = lu_desc.bDeviceProtocol;        desc->max_packet_size = lu_desc.bMaxPacketSize0; -      return SANE_STATUS_GOOD;      }  #else /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */      { @@ -3193,4 +4805,11 @@ sanei_usb_get_descriptor( SANE_Int dn,        return SANE_STATUS_UNSUPPORTED;      }  #endif /* not HAVE_LIBUSB_LEGACY && not HAVE_LIBUSB */ + +  if (testing_mode == sanei_usb_testing_mode_record) +    { +      sanei_usb_record_get_descriptor(dn, desc); +    } + +  return SANE_STATUS_GOOD;  } diff --git a/sanei/sanei_wire.c b/sanei/sanei_wire.c index a43cc2e..85021d1 100644 --- a/sanei/sanei_wire.c +++ b/sanei/sanei_wire.c @@ -67,7 +67,7 @@ sanei_w_space (Wire * w, size_t howmuch)    if (w->status != 0)      { -      DBG (1, "sanei_w_space: wire is in invalid state %d\n",  +      DBG (1, "sanei_w_space: wire is in invalid state %d\n",  	   w->status);        return;      } @@ -81,7 +81,7 @@ sanei_w_space (Wire * w, size_t howmuch)  	case WIRE_ENCODE:  	  nbytes = w->buffer.curr - w->buffer.start;  	  w->buffer.curr = w->buffer.start; -	  DBG (4, "sanei_w_space: ENCODE: sending %lu bytes\n",  +	  DBG (4, "sanei_w_space: ENCODE: sending %lu bytes\n",  	       (u_long) nbytes);  	  while (nbytes > 0)  	    { @@ -150,7 +150,7 @@ sanei_w_space (Wire * w, size_t howmuch)  }  void -sanei_w_void (Wire * w) +sanei_w_void (Wire * w, void __sane_unused__ * v)  {    DBG (3, "sanei_w_void: wire %d (void debug output)\n", w->io.fd);  } @@ -184,7 +184,7 @@ sanei_w_array (Wire * w, SANE_Word * len_ptr, void **v,        else  	DBG (1, "sanei_w_array: FREE: tried to free array but *len_ptr or *v "  	     "was NULL\n"); -	 +        DBG (4, "sanei_w_array: FREE: done\n");        return;      } @@ -200,14 +200,14 @@ sanei_w_array (Wire * w, SANE_Word * len_ptr, void **v,        return;      }    DBG (4, "sanei_w_array: array has %d elements\n", len); -       +    if (w->direction == WIRE_DECODE)      {        *len_ptr = len;        if (len)  	{ -	  if (((unsigned int) len) > MAX_MEM  -	      || ((unsigned int) len * element_size) > MAX_MEM  +	  if (((unsigned int) len) > MAX_MEM +	      || ((unsigned int) len * element_size) > MAX_MEM  	      || (w->allocated_memory + len * element_size) > MAX_MEM)  	    {  	      DBG (0, "sanei_w_array: DECODE: maximum amount of allocated memory " @@ -291,7 +291,7 @@ sanei_w_ptr (Wire * w, void **v, WireCodecFunc w_value, size_t value_size)  	    {  	      DBG (0, "sanei_w_ptr: DECODE: maximum amount of allocated memory "  		   "exceeded (limit: %u, new allocation: %lu, total: %lu bytes)\n", -		   MAX_MEM, (unsigned long)value_size,  +		   MAX_MEM, (unsigned long)value_size,  			   (unsigned long)(w->allocated_memory + value_size));  	      w->status = ENOMEM;  	      return; @@ -581,8 +581,8 @@ flush (Wire * w)  void  sanei_w_set_dir (Wire * w, WireDirection dir)  { -  DBG (3, "sanei_w_set_dir: wire %d, old direction WIRE_%s\n", w->io.fd,  -       w->direction == WIRE_ENCODE ? "ENCODE" :  +  DBG (3, "sanei_w_set_dir: wire %d, old direction WIRE_%s\n", w->io.fd, +       w->direction == WIRE_ENCODE ? "ENCODE" :         (w->direction == WIRE_DECODE ? "DECODE" : "FREE"));    if (w->direction == WIRE_DECODE && w->buffer.curr != w->buffer.end)      DBG (1, "sanei_w_set_dir: WARNING: will delete %lu bytes from buffer\n", @@ -591,8 +591,8 @@ sanei_w_set_dir (Wire * w, WireDirection dir)    w->direction = dir;    DBG (4, "sanei_w_set_dir: direction changed\n");    flush (w); -  DBG (3, "sanei_w_set_dir: wire %d, new direction WIRE_%s\n", w->io.fd,  -       dir == WIRE_ENCODE ? "ENCODE" :  +  DBG (3, "sanei_w_set_dir: wire %d, new direction WIRE_%s\n", w->io.fd, +       dir == WIRE_ENCODE ? "ENCODE" :         (dir == WIRE_DECODE ? "DECODE" : "FREE"));  } @@ -656,13 +656,13 @@ void  sanei_w_init (Wire * w, void (*codec_init_func) (Wire *))  {    DBG_INIT (); -   +    DBG (3, "sanei_w_init: initializing\n");    w->status = 0;    w->direction = WIRE_ENCODE;    w->buffer.size = 8192;    w->buffer.start = malloc (w->buffer.size); -   +    if (w->buffer.start == 0)      {        /* Malloc failed, so return an error. */ | 
