From 58912f68c2489bcee787599837447e0d64dfd61a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Wed, 24 May 2017 21:03:56 +0200 Subject: New upstream version 1.0.27 --- frontend/Makefile.am | 12 ++-- frontend/Makefile.in | 86 +++++++++++++++++--------- frontend/saned.c | 169 ++++++++++++++++++++++++++++++++++++--------------- frontend/scanimage.c | 100 ++++++++++++++++++++++++++---- frontend/sicc.c | 67 ++++++++++++++++++++ frontend/sicc.h | 19 ++++++ frontend/stiff.c | 99 ++++++++---------------------- 7 files changed, 381 insertions(+), 171 deletions(-) create mode 100644 frontend/sicc.c create mode 100644 frontend/sicc.h (limited to 'frontend') diff --git a/frontend/Makefile.am b/frontend/Makefile.am index 23061b3..525953f 100644 --- a/frontend/Makefile.am +++ b/frontend/Makefile.am @@ -14,21 +14,21 @@ else EXTRA_PROGRAMS += saned endif -AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include +AM_CPPFLAGS += -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -scanimage_SOURCES = scanimage.c stiff.c stiff.h +scanimage_SOURCES = scanimage.c sicc.c sicc.h stiff.c stiff.h scanimage_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - ../lib/libfelib.la @PNG_LIBS@ @JPEG_LIBS@ + $(PNG_LIBS) $(JPEG_LIBS) saned_SOURCES = saned.c saned_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - ../lib/libfelib.la @SYSLOG_LIBS@ @SYSTEMD_LIBS@ + $(SYSLOG_LIBS) $(SYSTEMD_LIBS) $(AVAHI_LIBS) test_SOURCES = test.c -test_LDADD = ../lib/liblib.la ../lib/libfelib.la ../backend/libsane.la +test_LDADD = ../lib/liblib.la ../backend/libsane.la tstbackend_SOURCES = tstbackend.c -tstbackend_LDADD = ../lib/liblib.la ../lib/libfelib.la ../backend/libsane.la +tstbackend_LDADD = ../lib/liblib.la ../backend/libsane.la clean-local: rm -f test tstbackend diff --git a/frontend/Makefile.in b/frontend/Makefile.in index 2e36e0e..9ea467f 100644 --- a/frontend/Makefile.in +++ b/frontend/Makefile.in @@ -86,11 +86,16 @@ subdir = frontend 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/ltoptions.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)/acinclude.m4 \ - $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/byteorder.m4 \ - $(top_srcdir)/m4/stdint.m4 $(top_srcdir)/configure.in + $(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 @@ -102,24 +107,25 @@ am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) am_saned_OBJECTS = saned.$(OBJEXT) saned_OBJECTS = $(am_saned_OBJECTS) +am__DEPENDENCIES_1 = saned_DEPENDENCIES = ../backend/libsane.la ../sanei/libsanei.la \ - ../lib/liblib.la ../lib/libfelib.la + ../lib/liblib.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) 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_scanimage_OBJECTS = scanimage.$(OBJEXT) stiff.$(OBJEXT) +am_scanimage_OBJECTS = scanimage.$(OBJEXT) sicc.$(OBJEXT) \ + stiff.$(OBJEXT) scanimage_OBJECTS = $(am_scanimage_OBJECTS) scanimage_DEPENDENCIES = ../backend/libsane.la ../sanei/libsanei.la \ - ../lib/liblib.la ../lib/libfelib.la + ../lib/liblib.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_test_OBJECTS = test.$(OBJEXT) test_OBJECTS = $(am_test_OBJECTS) -test_DEPENDENCIES = ../lib/liblib.la ../lib/libfelib.la \ - ../backend/libsane.la +test_DEPENDENCIES = ../lib/liblib.la ../backend/libsane.la am_tstbackend_OBJECTS = tstbackend.$(OBJEXT) tstbackend_OBJECTS = $(am_tstbackend_OBJECTS) -tstbackend_DEPENDENCIES = ../lib/liblib.la ../lib/libfelib.la \ - ../backend/libsane.la +tstbackend_DEPENDENCIES = ../lib/liblib.la ../backend/libsane.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -186,7 +192,11 @@ 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 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AM_LDFLAGS = @AM_LDFLAGS@ AR = @AR@ AS = @AS@ AUTOCONF = @AUTOCONF@ @@ -207,7 +217,7 @@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ -DISTCLEAN_FILES = @DISTCLEAN_FILES@ +DLH = @DLH@ DLLTOOL = @DLLTOOL@ DL_LIBS = @DL_LIBS@ DSYMUTIL = @DSYMUTIL@ @@ -220,34 +230,42 @@ 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@ -INCLUDES = @INCLUDES@ 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@ -LIBUSB_1_0_CFLAGS = @LIBUSB_1_0_CFLAGS@ -LIBUSB_1_0_LIBS = @LIBUSB_1_0_LIBS@ LIBV4L_CFLAGS = @LIBV4L_CFLAGS@ LIBV4L_LIBS = @LIBV4L_LIBS@ -LINKER_RPATH = @LINKER_RPATH@ LIPO = @LIPO@ LN_S = @LN_S@ LOCKPATH_GROUP = @LOCKPATH_GROUP@ +LTALLOCA = @LTALLOCA@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINDEX = @MAKEINDEX@ @@ -256,10 +274,10 @@ MANIFEST_TOOL = @MANIFEST_TOOL@ MATH_LIB = @MATH_LIB@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ NM = @NM@ NMEDIT = @NMEDIT@ -NUMBER_VERSION = @NUMBER_VERSION@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ @@ -272,10 +290,13 @@ 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@ @@ -297,12 +318,16 @@ 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@ @@ -358,19 +383,18 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AM_CPPFLAGS = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -scanimage_SOURCES = scanimage.c stiff.c stiff.h +scanimage_SOURCES = scanimage.c sicc.c sicc.h stiff.c stiff.h scanimage_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - ../lib/libfelib.la @PNG_LIBS@ @JPEG_LIBS@ + $(PNG_LIBS) $(JPEG_LIBS) saned_SOURCES = saned.c saned_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - ../lib/libfelib.la @SYSLOG_LIBS@ @SYSTEMD_LIBS@ + $(SYSLOG_LIBS) $(SYSTEMD_LIBS) $(AVAHI_LIBS) test_SOURCES = test.c -test_LDADD = ../lib/liblib.la ../lib/libfelib.la ../backend/libsane.la +test_LDADD = ../lib/liblib.la ../backend/libsane.la tstbackend_SOURCES = tstbackend.c -tstbackend_LDADD = ../lib/liblib.la ../lib/libfelib.la ../backend/libsane.la +tstbackend_LDADD = ../lib/liblib.la ../backend/libsane.la all: all-am .SUFFIXES: @@ -528,27 +552,31 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saned.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanimage.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sicc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stiff.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstbackend.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@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)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@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)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@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 $@ $< diff --git a/frontend/saned.c b/frontend/saned.c index 108512d..3bb99bb 100644 --- a/frontend/saned.c +++ b/frontend/saned.c @@ -82,6 +82,8 @@ #include #include +#include "lgetopt.h" + #if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) # include #else @@ -196,16 +198,19 @@ static AvahiEntryGroup *avahi_group = NULL; #endif #ifdef ENABLE_IPV6 -# define SANE_IN6_IS_ADDR_LOOPBACK(a) \ +# ifndef IN6_IS_ADDR_LOOPBACK +# define IN6_IS_ADDR_LOOPBACK(a) \ (((const uint32_t *) (a))[0] == 0 \ && ((const uint32_t *) (a))[1] == 0 \ && ((const uint32_t *) (a))[2] == 0 \ && ((const uint32_t *) (a))[3] == htonl (1)) - -#define SANE_IN6_IS_ADDR_V4MAPPED(a) \ +# endif +# ifndef IN6_IS_ADDR_V4MAPPED +# define IN6_IS_ADDR_V4MAPPED(a) \ ((((const uint32_t *) (a))[0] == 0) \ && (((const uint32_t *) (a))[1] == 0) \ && (((const uint32_t *) (a))[2] == htonl (0xffff))) +# endif #endif /* ENABLE_IPV6 */ #ifndef MAXHOSTNAMELEN @@ -247,6 +252,7 @@ static int num_handles; static int debug; static int run_mode; static Handle *handle; +static char *bind_addr; static union { int w; @@ -786,7 +792,7 @@ check_host (int fd) #ifdef ENABLE_IPV6 sin6 = &remote_address.sin6; - if (SANE_IN6_IS_ADDR_V4MAPPED (sin6->sin6_addr.s6_addr)) + if (IN6_IS_ADDR_V4MAPPED ((struct in6_addr *)sin6->sin6_addr.s6_addr)) { DBG (DBG_DBG, "check_host: detected an IPv4-mapped address\n"); remote_ipv4 = remote_ip + 7; @@ -843,7 +849,7 @@ check_host (int fd) break; #ifdef ENABLE_IPV6 case AF_INET6: - if (SANE_IN6_IS_ADDR_LOOPBACK (sin6->sin6_addr.s6_addr)) + if (IN6_IS_ADDR_LOOPBACK ((struct in6_addr *)sin6->sin6_addr.s6_addr)) { DBG (DBG_MSG, "check_host: remote host is IN6_LOOPBACK: access granted\n"); @@ -1428,7 +1434,7 @@ start_scan (Wire * w, int h, SANE_Start_Reply * reply) SANE_Handle be_handle; int fd, len; in_port_t data_port; - int ret; + int ret = -1; be_handle = handle[h].handle; @@ -1986,6 +1992,38 @@ process_request (Wire * w) return 1; } + /* Addresses CVE-2017-6318 (#315576, Debian BTS #853804) */ + /* This is done here (rather than in sanei/sanei_wire.c where + * it should be done) to minimize scope of impact and amount + * of code change. + */ + if (w->direction == WIRE_DECODE + && req.value_type == SANE_TYPE_STRING + && req.action == SANE_ACTION_GET_VALUE) + { + if (req.value) + { + /* FIXME: If req.value contains embedded NUL + * characters, this is wrong but we do not have + * access to the amount of memory allocated in + * sanei/sanei_wire.c at this point. + */ + w->allocated_memory -= (1 + strlen (req.value)); + free (req.value); + } + req.value = malloc (req.value_size); + if (!req.value) + { + w->status = ENOMEM; + DBG (DBG_ERR, + "process_request: (control_option) " + "h=%d (%s)\n", req.handle, strerror (w->status)); + return 1; + } + memset (req.value, 0, req.value_size); + w->allocated_memory += req.value_size; + } + can_authorize = 1; memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */ @@ -2807,13 +2845,13 @@ do_bindings (int *nfds, struct pollfd **fds) hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; - err = getaddrinfo (NULL, SANED_SERVICE_NAME, &hints, &res); + err = getaddrinfo (bind_addr, SANED_SERVICE_NAME, &hints, &res); if (err) { DBG (DBG_WARN, "do_bindings: \" %s \" service unknown on your host; you should add\n", SANED_SERVICE_NAME); DBG (DBG_WARN, "do_bindings: %s %d/tcp saned # SANE network scanner daemon\n", SANED_SERVICE_NAME, SANED_SERVICE_PORT); DBG (DBG_WARN, "do_bindings: to your /etc/services file (or equivalent). Proceeding anyway.\n"); - err = getaddrinfo (NULL, SANED_SERVICE_PORT_S, &hints, &res); + err = getaddrinfo (bind_addr, SANED_SERVICE_PORT_S, &hints, &res); if (err) { DBG (DBG_ERR, "do_bindings: getaddrinfo() failed even with numeric port: %s\n", gai_strerror (err)); @@ -2891,7 +2929,10 @@ do_bindings (int *nfds, struct pollfd **fds) memset (&sin, 0, sizeof (sin)); sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; + if(bind_addr) + sin.sin_addr.s_addr = inet_addr(bind_addr); + else + sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = port; DBG (DBG_DBG, "do_bindings: socket ()\n"); @@ -2923,7 +2964,7 @@ do_bindings (int *nfds, struct pollfd **fds) static void -run_standalone (int argc, char **argv) +run_standalone (char *user) { struct pollfd *fds = NULL; struct pollfd *fdp = NULL; @@ -2944,13 +2985,13 @@ run_standalone (int argc, char **argv) if (run_mode != SANED_RUN_DEBUG) { - if (argc > 2) + if (user) { - pwent = getpwnam(argv[2]); + pwent = getpwnam(user); if (pwent == NULL) { - DBG (DBG_ERR, "FATAL ERROR: user %s not found on system\n", argv[2]); + DBG (DBG_ERR, "FATAL ERROR: user %s not found on system\n", user); bail_out (1); } @@ -2981,7 +3022,7 @@ run_standalone (int argc, char **argv) while (grp->gr_mem[i]) { - if (strcmp(grp->gr_mem[i], argv[2]) == 0) + if (strcmp(grp->gr_mem[i], user) == 0) { int need_to_add = 1, j; @@ -3172,7 +3213,7 @@ run_standalone (int argc, char **argv) static void -run_inetd (int argc, char **argv) +run_inetd (char __sane_unused__ *sock) { int fd = -1; @@ -3238,18 +3279,13 @@ run_inetd (int argc, char **argv) close (dave_null); } -#ifndef HAVE_OS2_H - /* Unused in this function */ - argc = argc; - argv = argv; - -#else +#ifdef HAVE_OS2_H /* under OS/2, the socket handle is passed as argument on the command line; the socket handle is relative to IBM TCP/IP, so a call to impsockethandle() is required to add it to the EMX runtime */ - if (argc == 2) + if (sock) { - fd = _impsockhandle (atoi (argv[1]), 0); + fd = _impsockhandle (atoi (sock), 0); if (fd == -1) perror ("impsockhandle"); } @@ -3258,11 +3294,44 @@ run_inetd (int argc, char **argv) handle_connection(fd); } +static void usage(char *me, int err) +{ + fprintf (stderr, + "Usage: %s [OPTIONS]\n\n" + " Options:\n\n" + " -a, --alone[=user] run standalone and fork in background as `user'\n" + " -d, --debug[=level] run foreground with output to stdout\n" + " and debug level `level' (default is 2)\n" + " -s, --syslog[=level] run foreground with output to syslog\n" + " and debug level `level' (default is 2)\n" + " -b, --bind=addr bind address `addr'\n" + " -h, --help show this help message and exit\n", me); + + exit(err); +} + +static int debug; + +static struct option long_options[] = +{ +/* These options set a flag. */ + {"help", no_argument, 0, 'h'}, + {"alone", optional_argument, 0, 'a'}, + {"debug", optional_argument, 0, 'd'}, + {"syslog", optional_argument, 0, 's'}, + {"bind", required_argument, 0, 'b'}, + {0, 0, 0, 0 } +}; int main (int argc, char *argv[]) { char options[64] = ""; + char *user = NULL; + char *sock = NULL; + int c; + int long_index = 0; + debug = DBG_WARN; prog_name = strrchr (argv[0], '/'); @@ -3274,34 +3343,30 @@ main (int argc, char *argv[]) numchildren = 0; run_mode = SANED_RUN_INETD; - if (argc >= 2) + while((c = getopt_long(argc, argv,"ha::d::s::b:", long_options, &long_index )) != -1) { - if (strncmp (argv[1], "-a", 2) == 0) + switch(c) { + case 'a': run_mode = SANED_RUN_ALONE; - else if (strncmp (argv[1], "-d", 2) == 0) - { - run_mode = SANED_RUN_DEBUG; - log_to_syslog = SANE_FALSE; - } - else if (strncmp (argv[1], "-s", 2) == 0) + user = optarg; + break; + case 'd': + log_to_syslog = SANE_FALSE; + case 's': run_mode = SANED_RUN_DEBUG; - else - { - printf ("Usage: saned [ -a [ username ] | -d [ n ] | -s [ n ] ] | -h\n"); - if ((strncmp (argv[1], "-h", 2) == 0) || - (strncmp (argv[1], "--help", 6) == 0)) - exit (EXIT_SUCCESS); - else - exit (EXIT_FAILURE); - } - } - - if (run_mode == SANED_RUN_DEBUG) - { - if (argv[1][2]) - debug = atoi (argv[1] + 2); - - DBG (DBG_WARN, "main: starting debug mode (level %d)\n", debug); + if(optarg) + debug = atoi(optarg); + break; + case 'b': + bind_addr = optarg; + break; + case 'h': + usage(argv[0], EXIT_SUCCESS); + break; + default: + usage(argv[0], EXIT_FAILURE); + break; + } } if (log_to_syslog) @@ -3342,11 +3407,15 @@ main (int argc, char *argv[]) if ((run_mode == SANED_RUN_ALONE) || (run_mode == SANED_RUN_DEBUG)) { - run_standalone(argc, argv); + run_standalone(user); } else { - run_inetd(argc, argv); +#ifdef HAVE_OS2_H + if (argc == 2) + sock = argv[1]; +#endif + run_inetd(sock); } DBG (DBG_WARN, "saned exiting\n"); diff --git a/frontend/scanimage.c b/frontend/scanimage.c index 7f7c1f0..fe02750 100644 --- a/frontend/scanimage.c +++ b/frontend/scanimage.c @@ -56,6 +56,7 @@ #include "../include/sane/sanei.h" #include "../include/sane/saneopts.h" +#include "sicc.h" #include "stiff.h" #include "../include/md5.h" @@ -322,7 +323,7 @@ auth_callback (SANE_String_Const resource, } } -static RETSIGTYPE +static void sighandler (int signum) { static SANE_Bool first_time = SANE_TRUE; @@ -1165,9 +1166,14 @@ write_pnm_header (SANE_Frame format, int width, int height, int depth, FILE *ofp #ifdef HAVE_LIBPNG static void -write_png_header (SANE_Frame format, int width, int height, int depth, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr) +write_png_header (SANE_Frame format, int width, int height, int depth, int dpi, const char * icc_profile, FILE *ofp, png_structp* png_ptr, png_infop* info_ptr) { int color_type; + /* PNG does not have imperial reference units, so we must convert to metric. */ + /* There are nominally 39.3700787401575 inches in a meter. */ + const double pixels_per_meter = dpi * 39.3700787401575; + size_t icc_size = 0; + void *icc_buffer; *png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); @@ -1200,13 +1206,47 @@ write_png_header (SANE_Frame format, int width, int height, int depth, FILE *ofp depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_set_pHYs(*png_ptr, *info_ptr, + pixels_per_meter, pixels_per_meter, + PNG_RESOLUTION_METER); + + if (icc_profile) + { + icc_buffer = sanei_load_icc_profile(icc_profile, &icc_size); + if (icc_size > 0) + { + /* libpng will abort if the profile and image colour spaces do not match*/ + /* The data colour space field is at bytes 16 to 20 in an ICC profile */ + /* see: ICC.1:2010 § 7.2.6 */ + int is_gray_profile = strncmp((char *) icc_buffer + 16, "GRAY", 4) == 0; + int is_rgb_profile = strncmp((char *) icc_buffer + 16, "RGB ", 4) == 0; + if ((is_gray_profile && color_type == PNG_COLOR_TYPE_GRAY) || + (is_rgb_profile && color_type == PNG_COLOR_TYPE_RGB)) + { + png_set_iCCP(*png_ptr, *info_ptr, basename(icc_profile), PNG_COMPRESSION_TYPE_BASE, icc_buffer, icc_size); + } + else + { + if (is_gray_profile) + { + fprintf(stderr, "Ignoring 'GRAY' space ICC profile because the image is RGB.\n"); + } + if (is_rgb_profile) + { + fprintf(stderr, "Ignoring 'RGB ' space ICC profile because the image is Grayscale.\n"); + } + } + free(icc_buffer); + } + } + png_write_info(*png_ptr, *info_ptr); } #endif #ifdef HAVE_LIBJPEG static void -write_jpeg_header (SANE_Frame format, int width, int height, FILE *ofp, struct jpeg_compress_struct *cinfo, struct jpeg_error_mgr *jerr) +write_jpeg_header (SANE_Frame format, int width, int height, int dpi, FILE *ofp, struct jpeg_compress_struct *cinfo, struct jpeg_error_mgr *jerr) { cinfo->err = jpeg_std_error(jerr); jpeg_create_compress(cinfo); @@ -1231,6 +1271,11 @@ write_jpeg_header (SANE_Frame format, int width, int height, FILE *ofp, struct j } jpeg_set_defaults(cinfo); + /* jpeg_set_defaults overrides density, be careful. */ + cinfo->density_unit = 1; /* Inches */ + cinfo->X_density = cinfo->Y_density = dpi; + cinfo->write_JFIF_header = TRUE; + jpeg_set_quality(cinfo, 75, TRUE); jpeg_start_compress(cinfo, TRUE); } @@ -1379,13 +1424,15 @@ scan_it (FILE *ofp) #ifdef HAVE_LIBPNG case OUTPUT_PNG: write_png_header (parm.format, parm.pixels_per_line, - parm.lines, parm.depth, ofp, &png_ptr, &info_ptr); + parm.lines, parm.depth, resolution_value, + icc_profile, ofp, &png_ptr, &info_ptr); break; #endif #ifdef HAVE_LIBJPEG case OUTPUT_JPEG: write_jpeg_header (parm.format, parm.pixels_per_line, - parm.lines, ofp, &cinfo, &jerr); + parm.lines, resolution_value, + ofp, &cinfo, &jerr); break; #endif } @@ -1529,6 +1576,21 @@ scan_it (FILE *ofp) for(j = 0; j < parm.bytes_per_line; j++) pngbuf[j] = ~pngbuf[j]; } +#ifndef WORDS_BIGENDIAN + /* SANE is endian-native, PNG is big-endian, */ + /* see: https://www.w3.org/TR/2003/REC-PNG-20031110/#7Integers-and-byte-order */ + if (parm.depth == 16) + { + int j; + for (j = 0; j < parm.bytes_per_line; j += 2) + { + SANE_Byte LSB; + LSB = pngbuf[j]; + pngbuf[j] = pngbuf[j + 1]; + pngbuf[j + 1] = LSB; + } + } +#endif png_write_row(png_ptr, pngbuf); i += parm.bytes_per_line - pngrow; left -= parm.bytes_per_line - pngrow; @@ -1635,13 +1697,15 @@ scan_it (FILE *ofp) #ifdef HAVE_LIBPNG case OUTPUT_PNG: write_png_header (parm.format, parm.pixels_per_line, - image.height, parm.depth, ofp, &png_ptr, &info_ptr); + image.height, parm.depth, resolution_value, + icc_profile, ofp, &png_ptr, &info_ptr); break; #endif #ifdef HAVE_LIBJPEG case OUTPUT_JPEG: write_jpeg_header (parm.format, parm.pixels_per_line, - parm.lines, ofp, &cinfo, &jerr); + parm.lines, resolution_value, + ofp, &cinfo, &jerr); break; #endif } @@ -2474,9 +2538,16 @@ List of available devices:", prog_name); ofp = stdout; if (batch) - fprintf (stderr, - "Scanning %d pages, incrementing by %d, numbering from %d\n", - batch_count, batch_increment, batch_start_at); + { + fputs("Scanning ", stderr); + if (batch_count == BATCH_COUNT_UNLIMITED) + fputs("infinity", stderr); + else + fprintf(stderr, "%d", batch_count); + fprintf (stderr, + " page%s, incrementing by %d, numbering from %d\n", + batch_count == 1 ? "" : "s", batch_increment, batch_start_at); + } else if(isatty(fileno(ofp))){ fprintf (stderr,"%s: output is not a file, exiting\n", prog_name); @@ -2509,8 +2580,6 @@ List of available devices:", prog_name); if (readbuf2 == NULL) { - fprintf (stderr, "Batch terminated, %d pages scanned\n", - (n - batch_increment)); if (ofp) { fclose (ofp); @@ -2612,6 +2681,13 @@ List of available devices:", prog_name); && (batch_count == BATCH_COUNT_UNLIMITED || --batch_count)) && SANE_STATUS_GOOD == status); + if (batch) + { + int num_pgs = (n - batch_start_at) / batch_increment; + fprintf (stderr, "Batch terminated, %d page%s scanned\n", + num_pgs, num_pgs == 1 ? "" : "s"); + } + if (batch && SANE_STATUS_NO_DOCS == status && (batch_count == BATCH_COUNT_UNLIMITED) diff --git a/frontend/sicc.c b/frontend/sicc.c new file mode 100644 index 0000000..c93e5c3 --- /dev/null +++ b/frontend/sicc.c @@ -0,0 +1,67 @@ +/* Load an ICC profile for embedding in an output file + Copyright (C) 2017 Aaron Muir Hamilton + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "../include/sane/config.h" + +#include +#include +#include + +void * +sanei_load_icc_profile (const char *path, size_t *size) +{ + FILE *fd = NULL; + size_t stated_size = 0; + void *profile = NULL; + struct stat s; + + fd = fopen(path, "r"); + + if (!fd) + { + fprintf(stderr, "Could not open ICC profile %s\n", path); + } + else + { + fstat(fileno(fd), &s); + stated_size = 16777216 * fgetc(fd) + 65536 * fgetc(fd) + 256 * fgetc(fd) + fgetc(fd); + rewind(fd); + + if (stated_size > (size_t) s.st_size) + { + fprintf(stderr, "Ignoring ICC profile because file %s is shorter than the profile\n", path); + } + else + { + profile = malloc(stated_size); + + if (fread(profile, stated_size, 1, fd) != 1) + { + fprintf(stderr, "Error reading ICC profile %s\n", path); + free(profile); + } + else + { + fclose(fd); + *size = stated_size; + return profile; + } + } + fclose(fd); + } + return NULL; +} diff --git a/frontend/sicc.h b/frontend/sicc.h new file mode 100644 index 0000000..5c225da --- /dev/null +++ b/frontend/sicc.h @@ -0,0 +1,19 @@ +/* Load an ICC profile for embedding in an output file + Copyright (C) 2017 Aaron Muir Hamilton + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +void * +sanei_load_icc_profile (const char *path, size_t *size); diff --git a/frontend/stiff.c b/frontend/stiff.c index 01d845b..c9153e5 100644 --- a/frontend/stiff.c +++ b/frontend/stiff.c @@ -1,6 +1,7 @@ /* Create SANE/tiff headers TIFF interfacing routines for SANE Copyright (C) 2000 Peter Kirchgessner Copyright (C) 2002 Oliver Rauch: added tiff ICC profile + Copyright (C) 2017 Aaron Muir Hamilton This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -20,6 +21,7 @@ 2000-11-19, PK: Color TIFF-header: write 3 values for bits per sample 2001-12-16, PK: Write fill order tag for b/w-images 2002-08-27, OR: Added tiff tag for ICC profile + 2017-04-16, AMH: Separate ICC profile loading into a separate file */ #ifdef _AIX # include "../include/lalloca.h" /* MUST come first for AIX! */ @@ -31,6 +33,7 @@ #include "../include/sane/config.h" #include "../include/sane/sane.h" +#include "sicc.h" #include "stiff.h" typedef struct { @@ -269,22 +272,12 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth, int strip_bytecount; int ntags; int motorola, bps, maxsamplevalue; - FILE *icc_file = 0; - int icc_len = -1; + void *icc_buffer = NULL; + size_t icc_size = 0; if (icc_profile) { - icc_file = fopen(icc_profile, "r"); - - if (!icc_file) - { - fprintf(stderr, "Could not open ICC profile %s\n", icc_profile); - } - else - { - icc_len = 16777216 * fgetc(icc_file) + 65536 * fgetc(icc_file) + 256 * fgetc(icc_file) + fgetc(icc_file); - rewind(icc_file); - } + icc_buffer = sanei_load_icc_profile(icc_profile, &icc_size); } ifd = create_ifd (); @@ -302,10 +295,10 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth, data_size += 2*4 + 2*4; } - if (icc_len > 0) /* if icc profile exists add memory for tag */ + if (icc_size > 0) /* if icc profile exists add memory for tag */ { ntags += 1; - data_size += icc_len; + data_size += icc_size; } ifd_size = 2 + ntags*12 + 4; @@ -355,10 +348,10 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth, add_ifd_entry (ifd, 296, IFDE_TYP_SHORT, 1, 2); } - if (icc_len > 0) /* add ICC-profile TAG */ + if (icc_size > 0) /* add ICC-profile TAG */ { - add_ifd_entry(ifd, 34675, 7, icc_len, data_offset); - data_offset += icc_len; + add_ifd_entry(ifd, 34675, 7, (int) icc_size, data_offset); + data_offset += icc_size; } /* I prefer motorola format. Its human readable. But for 16 bit, */ @@ -383,33 +376,16 @@ write_tiff_grey_header (FILE *fptr, int width, int height, int depth, write_i4 (fptr, 1, motorola); } - /* Write ICC profile */ - if (icc_len > 0) + if (icc_size > 0) { - int i; - for (i=0; i 0) /* if icc profile exists add memory for tag */ + if (icc_size > 0) /* if icc profile exists add memory for tag */ { ntags += 1; - data_size += icc_len; + data_size += icc_size; } @@ -513,10 +479,10 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth, add_ifd_entry (ifd, 296, IFDE_TYP_SHORT, 1, 2); } - if (icc_len > 0) /* add ICC-profile TAG */ + if (icc_size > 0) /* add ICC-profile TAG */ { - add_ifd_entry(ifd, 34675, 7, icc_len, data_offset); - data_offset += icc_len; + add_ifd_entry(ifd, 34675, 7, (int) icc_size, data_offset); + data_offset += icc_size; } @@ -558,27 +524,12 @@ write_tiff_color_header (FILE *fptr, int width, int height, int depth, } /* Write ICC profile */ - if (icc_len > 0) + if (icc_size > 0) { - int i; - for (i=0; i Date: Wed, 31 Jul 2019 16:59:49 +0200 Subject: New upstream version 1.0.28 --- frontend/.gitignore | 2 + frontend/Makefile.in | 804 -------------------------------------------------- frontend/saned.c | 530 +++++++++++++++++++-------------- frontend/scanimage.c | 130 +++++++- frontend/test.c | 6 +- frontend/tstbackend.c | 299 ++++++++++--------- 6 files changed, 584 insertions(+), 1187 deletions(-) create mode 100644 frontend/.gitignore delete mode 100644 frontend/Makefile.in (limited to 'frontend') diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 0000000..90f73a9 --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1,2 @@ +saned +scanimage diff --git a/frontend/Makefile.in b/frontend/Makefile.in deleted file mode 100644 index 9ea467f..0000000 --- a/frontend/Makefile.in +++ /dev/null @@ -1,804 +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@ -EXTRA_PROGRAMS = test$(EXEEXT) tstbackend$(EXEEXT) $(am__EXEEXT_1) -bin_PROGRAMS = scanimage$(EXEEXT) -@COMPILE_SANED_TRUE@sbin_PROGRAMS = saned$(EXEEXT) -@COMPILE_SANED_FALSE@am__append_1 = saned -subdir = frontend -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 = -@COMPILE_SANED_FALSE@am__EXEEXT_1 = saned$(EXEEXT) -am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" -PROGRAMS = $(bin_PROGRAMS) $(sbin_PROGRAMS) -am_saned_OBJECTS = saned.$(OBJEXT) -saned_OBJECTS = $(am_saned_OBJECTS) -am__DEPENDENCIES_1 = -saned_DEPENDENCIES = ../backend/libsane.la ../sanei/libsanei.la \ - ../lib/liblib.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -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_scanimage_OBJECTS = scanimage.$(OBJEXT) sicc.$(OBJEXT) \ - stiff.$(OBJEXT) -scanimage_OBJECTS = $(am_scanimage_OBJECTS) -scanimage_DEPENDENCIES = ../backend/libsane.la ../sanei/libsanei.la \ - ../lib/liblib.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_test_OBJECTS = test.$(OBJEXT) -test_OBJECTS = $(am_test_OBJECTS) -test_DEPENDENCIES = ../lib/liblib.la ../backend/libsane.la -am_tstbackend_OBJECTS = tstbackend.$(OBJEXT) -tstbackend_OBJECTS = $(am_tstbackend_OBJECTS) -tstbackend_DEPENDENCIES = ../lib/liblib.la ../backend/libsane.la -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 = $(saned_SOURCES) $(scanimage_SOURCES) $(test_SOURCES) \ - $(tstbackend_SOURCES) -DIST_SOURCES = $(saned_SOURCES) $(scanimage_SOURCES) $(test_SOURCES) \ - $(tstbackend_SOURCES) -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 -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@ -scanimage_SOURCES = scanimage.c sicc.c sicc.h stiff.c stiff.h -scanimage_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - $(PNG_LIBS) $(JPEG_LIBS) - -saned_SOURCES = saned.c -saned_LDADD = ../backend/libsane.la ../sanei/libsanei.la ../lib/liblib.la \ - $(SYSLOG_LIBS) $(SYSTEMD_LIBS) $(AVAHI_LIBS) - -test_SOURCES = test.c -test_LDADD = ../lib/liblib.la ../backend/libsane.la -tstbackend_SOURCES = tstbackend.c -tstbackend_LDADD = ../lib/liblib.la ../backend/libsane.la -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 frontend/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu frontend/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): -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list -install-sbinPROGRAMS: $(sbin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-sbinPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(sbindir)" && rm -f $$files - -clean-sbinPROGRAMS: - @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -saned$(EXEEXT): $(saned_OBJECTS) $(saned_DEPENDENCIES) $(EXTRA_saned_DEPENDENCIES) - @rm -f saned$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(saned_OBJECTS) $(saned_LDADD) $(LIBS) - -scanimage$(EXEEXT): $(scanimage_OBJECTS) $(scanimage_DEPENDENCIES) $(EXTRA_scanimage_DEPENDENCIES) - @rm -f scanimage$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(scanimage_OBJECTS) $(scanimage_LDADD) $(LIBS) - -test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) - @rm -f test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) - -tstbackend$(EXEEXT): $(tstbackend_OBJECTS) $(tstbackend_DEPENDENCIES) $(EXTRA_tstbackend_DEPENDENCIES) - @rm -f tstbackend$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(tstbackend_OBJECTS) $(tstbackend_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/saned.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scanimage.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sicc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stiff.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tstbackend.Po@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 $(PROGRAMS) -installdirs: - for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -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-binPROGRAMS clean-generic clean-libtool clean-local \ - clean-sbinPROGRAMS 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-binPROGRAMS install-sbinPROGRAMS - -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: uninstall-binPROGRAMS uninstall-sbinPROGRAMS - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic clean-libtool clean-local \ - clean-sbinPROGRAMS 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-binPROGRAMS 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-sbinPROGRAMS 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 uninstall-binPROGRAMS \ - uninstall-sbinPROGRAMS - - -clean-local: - rm -f test tstbackend - -# 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/frontend/saned.c b/frontend/saned.c index 3bb99bb..ac5e700 100644 --- a/frontend/saned.c +++ b/frontend/saned.c @@ -87,7 +87,7 @@ #if defined(HAVE_SYS_POLL_H) && defined(HAVE_POLL) # include #else -/* +/* * This replacement poll() using select() is only designed to cover * our needs in run_standalone(). It should probably be extended... */ @@ -203,13 +203,13 @@ static AvahiEntryGroup *avahi_group = NULL; (((const uint32_t *) (a))[0] == 0 \ && ((const uint32_t *) (a))[1] == 0 \ && ((const uint32_t *) (a))[2] == 0 \ - && ((const uint32_t *) (a))[3] == htonl (1)) + && ((const uint32_t *) (a))[3] == htonl (1)) # endif # ifndef IN6_IS_ADDR_V4MAPPED # define IN6_IS_ADDR_V4MAPPED(a) \ ((((const uint32_t *) (a))[0] == 0) \ && (((const uint32_t *) (a))[1] == 0) \ - && (((const uint32_t *) (a))[2] == htonl (0xffff))) + && (((const uint32_t *) (a))[2] == htonl (0xffff))) # endif #endif /* ENABLE_IPV6 */ @@ -251,6 +251,9 @@ static Wire wire; static int num_handles; static int debug; static int run_mode; +static int run_foreground; +static int run_once; +static int data_connect_timeout = 4000; static Handle *handle; static char *bind_addr; static union @@ -298,9 +301,7 @@ static SANE_Bool log_to_syslog = SANE_TRUE; static int process_request (Wire * w); #define SANED_RUN_INETD 0 -#define SANED_RUN_DEBUG 1 -#define SANED_RUN_ALONE 2 - +#define SANED_RUN_ALONE 1 #define DBG_ERR 1 #define DBG_WARN 2 @@ -402,7 +403,7 @@ auth_callback (SANE_String_Const res, break; default: - DBG (DBG_WARN, + DBG (DBG_WARN, "auth_callback: called for unexpected request %d (resource=%s)\n", current_request, res); break; @@ -430,7 +431,7 @@ auth_callback (SANE_String_Const res, { DBG (DBG_WARN, "auth_callback: bad procedure number %d " - "(expected: %d, resource=%s)\n", procnum, SANE_NET_AUTHORIZE, + "(expected: %d, resource=%s)\n", procnum, SANE_NET_AUTHORIZE, res); return; } @@ -565,7 +566,7 @@ check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask) int cidr; int i, err; char *end; - uint32_t mask; + uint32_t mask; struct sockaddr_in *base; struct addrinfo hints; struct addrinfo *res; @@ -573,7 +574,7 @@ check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask) cidr = -1; cidr = strtol (netmask, &end, 10); - + /* Sanity check on the cidr value */ if ((cidr < 0) || (cidr > 32) || (end == netmask)) { @@ -584,13 +585,13 @@ check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask) mask = 0; cidr -= 8; - /* Build a bitmask out of the CIDR value */ + /* Build a bitmask out of the CIDR value */ for (i = 3; cidr >= 0; i--) { mask |= (0xff << (8 * i)); cidr -= 8; } - + if (cidr < 0) mask |= (cidrtomask[cidr + 8] << (8 * i)); @@ -600,7 +601,7 @@ check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask) memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = PF_INET; - + err = getaddrinfo (base_ip, NULL, &hints, &res); if (err) { @@ -616,9 +617,9 @@ check_v4_in_range (struct sockaddr_in *sin, char *base_ip, char *netmask) */ if ((base->sin_addr.s_addr & mask) == (sin->sin_addr.s_addr & mask)) ret = SANE_TRUE; - + freeaddrinfo (res); - + return ret; } @@ -649,17 +650,17 @@ check_v6_in_range (struct sockaddr_in6 *sin6, char *base_ip, char *netmask) memset (mask, 0, (16 * sizeof (unsigned int))); cidr -= 8; - + /* Build a bitmask out of the CIDR value */ for (i = 0; cidr >= 0; i++) { mask[i] = 0xff; cidr -= 8; } - + if (cidr < 0) mask[i] = cidrtomask[cidr + 8]; - + /* get a sockaddr_in6 representing the base IP address */ memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; @@ -686,9 +687,9 @@ check_v6_in_range (struct sockaddr_in6 *sin6, char *base_ip, char *netmask) break; } } - + freeaddrinfo (res); - + return ret; } # endif /* ENABLE_IPV6 */ @@ -699,12 +700,12 @@ check_v4_in_range (struct in_addr *inaddr, struct in_addr *base, char *netmask) int cidr; int i; char *end; - uint32_t mask; + uint32_t mask; SANE_Bool ret = SANE_FALSE; cidr = -1; cidr = strtol (netmask, &end, 10); - + /* sanity check on the cidr value */ if ((cidr < 0) || (cidr > 32) || (end == netmask)) { @@ -714,14 +715,14 @@ check_v4_in_range (struct in_addr *inaddr, struct in_addr *base, char *netmask) mask = 0; cidr -= 8; - + /* Build a bitmask out of the CIDR value */ for (i = 3; cidr >= 0; i--) { mask |= (0xff << (8 * i)); cidr -= 8; } - + if (cidr < 0) mask |= (cidrtomask[cidr + 8] << (8 * i)); @@ -733,7 +734,7 @@ check_v4_in_range (struct in_addr *inaddr, struct in_addr *base, char *netmask) */ if ((base->s_addr & mask) == (inaddr->s_addr & mask)) ret = SANE_TRUE; - + return ret; } #endif /* SANED_USES_AF_INDEP */ @@ -801,7 +802,7 @@ check_host (int fd) memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = PF_INET; - + err = getaddrinfo (remote_ipv4, NULL, &hints, &res); if (err) { @@ -901,13 +902,13 @@ check_host (int fd) { DBG (DBG_DBG, "check_host: local hostname(s) (from DNS): %s\n", resp->ai_canonname); - + err = getnameinfo (resp->ai_addr, resp->ai_addrlen, text_addr, sizeof (text_addr), NULL, 0, NI_NUMERICHOST); if (err) strncpy (text_addr, "[error]", 8); -#ifdef ENABLE_IPV6 +#ifdef ENABLE_IPV6 if ((strcasecmp (text_addr, remote_ip) == 0) || ((IPv4map == SANE_TRUE) && (strcmp (text_addr, remote_ipv4) == 0))) #else @@ -915,18 +916,18 @@ check_host (int fd) #endif /* ENABLE_IPV6 */ { DBG (DBG_MSG, "check_host: remote host has same addr as local: access granted\n"); - + freeaddrinfo (res); res = NULL; return SANE_STATUS_GOOD; } } - + freeaddrinfo (res); res = NULL; - - DBG (DBG_DBG, + + DBG (DBG_DBG, "check_host: remote host doesn't have same addr as local\n"); } @@ -947,8 +948,8 @@ check_host (int fd) config_file_names[j], strerror (errno)); continue; } - - while (!access_ok && sanei_config_read (config_line_buf, + + while (!access_ok && sanei_config_read (config_line_buf, sizeof (config_line_buf), fp)) { config_line = config_line_buf; /* from now on, use a pointer */ @@ -993,7 +994,7 @@ check_host (int fd) if (strcmp (config_line, "+") == 0) { access_ok = 1; - DBG (DBG_DBG, + DBG (DBG_DBG, "check_host: access granted from any host (`+')\n"); } /* compare remote_ip (remote IP address) to the config_line */ @@ -1033,7 +1034,7 @@ check_host (int fd) memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = PF_INET; - + err = getaddrinfo (remote_ipv4, NULL, &hints, &res); if (err) DBG (DBG_DBG, "check_host: getaddrinfo() failed: %s\n", gai_strerror (err)); @@ -1044,7 +1045,7 @@ check_host (int fd) if ((SS_FAMILY(remote_address.ss) == AF_INET) || (IPv4map == SANE_TRUE)) { - + if (check_v4_in_range (sin, config_line, netmask)) { DBG (DBG_DBG, "check_host: access granted from IP address %s (in subnet %s/%s)\n", @@ -1056,7 +1057,7 @@ check_host (int fd) /* restore the old sin pointer */ sin = &remote_address.sin; } - + if (res != NULL) { freeaddrinfo (res); @@ -1086,11 +1087,11 @@ check_host (int fd) #else hints.ai_family = PF_INET; #endif /* ENABLE_IPV6 */ - + err = getaddrinfo (config_line, NULL, &hints, &res); if (err) { - DBG (DBG_DBG, + DBG (DBG_DBG, "check_host: getaddrinfo for `%s' failed: %s\n", config_line, gai_strerror (err)); DBG (DBG_MSG, "check_host: entry isn't an IP address " @@ -1105,19 +1106,19 @@ check_host (int fd) sizeof (text_addr), NULL, 0, NI_NUMERICHOST); if (err) strncpy (text_addr, "[error]", 8); - - DBG (DBG_MSG, - "check_host: DNS lookup returns IP address: %s\n", - text_addr); - -#ifdef ENABLE_IPV6 + + DBG (DBG_MSG, + "check_host: DNS lookup returns IP address: %s\n", + text_addr); + +#ifdef ENABLE_IPV6 if ((strcasecmp (text_addr, remote_ip) == 0) || ((IPv4map == SANE_TRUE) && (strcmp (text_addr, remote_ipv4) == 0))) #else if (strcmp (text_addr, remote_ip) == 0) #endif /* ENABLE_IPV6 */ access_ok = 1; - + if (access_ok) break; } @@ -1128,10 +1129,10 @@ check_host (int fd) } fclose (fp); } - + if (access_ok) return SANE_STATUS_GOOD; - + return SANE_STATUS_ACCESS_DENIED; } @@ -1150,7 +1151,7 @@ check_host (int fd) char hostname[MAXHOSTNAMELEN]; char *r_hostname; static struct in_addr config_line_address; - + int len; FILE *fp; @@ -1164,7 +1165,7 @@ check_host (int fd) } r_hostname = inet_ntoa (sin.sin_addr); remote_ip = strdup (r_hostname); - DBG (DBG_WARN, "check_host: access by remote host: %s\n", + DBG (DBG_WARN, "check_host: access by remote host: %s\n", remote_ip); /* Save remote address for check of control and data connections */ memcpy (&remote_address, &sin.sin_addr, sizeof (remote_address)); @@ -1203,7 +1204,7 @@ check_host (int fd) { DBG (DBG_DBG, "check_host: local hostname (from DNS): %s\n", he->h_name); - + if ((he->h_length == 4) || (he->h_addrtype == AF_INET)) { if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr, @@ -1211,9 +1212,9 @@ check_host (int fd) strcpy (text_addr, "[error]"); DBG (DBG_DBG, "check_host: local host address (from DNS): %s\n", text_addr); - if (memcmp (he->h_addr_list[0], &remote_address.s_addr, 4) == 0) + if (memcmp (he->h_addr_list[0], &remote_address.s_addr, 4) == 0) { - DBG (DBG_MSG, + DBG (DBG_MSG, "check_host: remote host has same addr as local: " "access accepted\n"); return SANE_STATUS_GOOD; @@ -1246,8 +1247,8 @@ check_host (int fd) config_file_names[j], strerror (errno)); continue; } - - while (!access_ok && sanei_config_read (config_line_buf, + + while (!access_ok && sanei_config_read (config_line_buf, sizeof (config_line_buf), fp)) { config_line = config_line_buf; /* from now on, use a pointer */ @@ -1275,14 +1276,14 @@ check_host (int fd) if (strcmp (config_line, "+") == 0) { access_ok = 1; - DBG (DBG_DBG, + DBG (DBG_DBG, "check_host: access accepted from any host (`+')\n"); } else { if (inet_pton (AF_INET, config_line, &config_line_address) > 0) { - if (memcmp (&remote_address.s_addr, + if (memcmp (&remote_address.s_addr, &config_line_address.s_addr, 4) == 0) access_ok = 1; else if (netmask != NULL) @@ -1297,13 +1298,13 @@ check_host (int fd) } else { - DBG (DBG_DBG, + DBG (DBG_DBG, "check_host: inet_pton for `%s' failed\n", config_line); he = gethostbyname (config_line); if (!he) { - DBG (DBG_DBG, + DBG (DBG_DBG, "check_host: gethostbyname for `%s' failed: %s\n", config_line, hstrerror (h_errno)); DBG (DBG_MSG, "check_host: entry isn't an IP address " @@ -1313,10 +1314,10 @@ check_host (int fd) if (!inet_ntop (he->h_addrtype, he->h_addr_list[0], text_addr, sizeof (text_addr))) strcpy (text_addr, "[error]"); - DBG (DBG_MSG, + DBG (DBG_MSG, "check_host: DNS lookup returns IP address: %s\n", text_addr); - if (memcmp (&remote_address.s_addr, + if (memcmp (&remote_address.s_addr, he->h_addr_list[0], 4) == 0) access_ok = 1; } @@ -1356,7 +1357,7 @@ init (Wire * w) DBG (DBG_ERR, "init: bad status after sanei_w_set_dir: %d\n", w->status); return -1; } - + sanei_w_word (w, &word); /* decode procedure number */ if (w->status || word != SANE_NET_INIT) { @@ -1658,7 +1659,7 @@ do_scan (Wire * w, int h, int data_fd) long int nwritten; SANE_Int length; size_t nbytes; - + DBG (3, "do_scan: start\n"); FD_ZERO (&rd_mask); @@ -1699,8 +1700,8 @@ do_scan (Wire * w, int h, int data_fd) FD_CLR (be_fd, &rd_mask); be_fd = -1; /* only set status_dirty if EOF hasn't been already detected */ - if (status == SANE_STATUS_GOOD) - status_dirty = 1; + if (status == SANE_STATUS_GOOD) + status_dirty = 1; status = SANE_STATUS_EOF; DBG (DBG_INFO, "do_scan: select_fd was closed --> EOF\n"); continue; @@ -1723,17 +1724,18 @@ do_scan (Wire * w, int h, int data_fd) nbytes = bytes_in_buf; if (writer + nbytes > sizeof (buf)) nbytes = sizeof (buf) - writer; - DBG (DBG_INFO, + DBG (DBG_INFO, "do_scan: trying to write %d bytes to client\n", nbytes); nwritten = write (data_fd, buf + writer, nbytes); - DBG (DBG_INFO, + DBG (DBG_INFO, "do_scan: wrote %ld bytes to client\n", nwritten); if (nwritten < 0) { DBG (DBG_ERR, "do_scan: write failed (%s)\n", strerror (errno)); status = SANE_STATUS_CANCELLED; + handle[h].docancel = 1; break; } bytes_in_buf -= nwritten; @@ -1791,7 +1793,7 @@ do_scan (Wire * w, int h, int data_fd) reader = store_reclen (buf, sizeof (buf), reader, 0xffffffff); buf[reader] = status; bytes_in_buf += 5; - DBG (DBG_MSG, "do_scan: statuscode `%s' was added to buffer\n", + DBG (DBG_MSG, "do_scan: statuscode `%s' was added to buffer\n", sane_strstatus(status)); } @@ -1799,13 +1801,19 @@ do_scan (Wire * w, int h, int data_fd) { DBG (DBG_MSG, "do_scan: processing RPC request on fd %d\n", w->io.fd); - process_request (w); + if(process_request (w) < 0) + handle[h].docancel = 1; + if (handle[h].docancel) break; } } while (status == SANE_STATUS_GOOD || bytes_in_buf > 0 || status_dirty); DBG (DBG_MSG, "do_scan: done, status=%s\n", sane_strstatus (status)); + + if(handle[h].docancel) + sane_cancel (handle[h].handle); + handle[h].docancel = 0; handle[h].scanning = 0; } @@ -1854,7 +1862,7 @@ process_request (Wire * w) sanei_w_string (w, &name); if (w->status) { - DBG (DBG_ERR, + DBG (DBG_ERR, "process_request: (open) error while decoding args (%s)\n", strerror (w->status)); return 1; @@ -1871,7 +1879,7 @@ process_request (Wire * w) can_authorize = 1; resource = strdup (name); - + if (strlen(resource) == 0) { const SANE_Device **device_list; @@ -1879,8 +1887,8 @@ process_request (Wire * w) DBG(DBG_DBG, "process_request: (open) strlen(resource) == 0\n"); free (resource); - if ((i = sane_get_devices (&device_list, SANE_TRUE)) != - SANE_STATUS_GOOD) + if ((i = sane_get_devices (&device_list, SANE_TRUE)) != + SANE_STATUS_GOOD) { DBG(DBG_ERR, "process_request: (open) sane_get_devices failed\n"); memset (&reply, 0, sizeof (reply)); @@ -1889,7 +1897,7 @@ process_request (Wire * w) break; } - if ((device_list == NULL) || (device_list[0] == NULL)) + if ((device_list == NULL) || (device_list[0] == NULL)) { DBG(DBG_ERR, "process_request: (open) device_list[0] == 0\n"); memset (&reply, 0, sizeof (reply)); @@ -1907,7 +1915,7 @@ process_request (Wire * w) if (sanei_authorize (resource, "saned", auth_callback) != SANE_STATUS_GOOD) { - DBG (DBG_ERR, "process_request: access to resource `%s' denied\n", + DBG (DBG_ERR, "process_request: access to resource `%s' denied\n", resource); free (resource); memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */ @@ -1915,12 +1923,12 @@ process_request (Wire * w) } else { - DBG (DBG_MSG, "process_request: access to resource `%s' granted\n", + DBG (DBG_MSG, "process_request: access to resource `%s' granted\n", resource); free (resource); memset (&reply, 0, sizeof (reply)); /* avoid leaking bits */ reply.status = sane_open (name, &be_handle); - DBG (DBG_MSG, "process_request: sane_open returned: %s\n", + DBG (DBG_MSG, "process_request: sane_open returned: %s\n", sane_strstatus (reply.status)); } @@ -2062,7 +2070,7 @@ process_request (Wire * w) case SANE_NET_START: { SANE_Start_Reply reply; - int fd = -1, data_fd; + int fd = -1, data_fd = -1; h = decode_handle (w, "start"); if (h < 0) @@ -2087,9 +2095,36 @@ process_request (Wire * w) char text_addr[64]; int len; int error; + struct pollfd fds[1]; + int ret; - DBG (DBG_MSG, "process_request: waiting for data connection\n"); - data_fd = accept (fd, 0, 0); + fds->fd = fd; + fds->events = POLLIN; + + DBG (DBG_MSG, "process_request: waiting 4s for data connection\n"); + if(data_connect_timeout) + { + while (1) + { + ret = poll (fds, 1, data_connect_timeout); + if (ret < 0) + { + if (errno == EINTR) + continue; + else + { + DBG (DBG_ERR, "run_standalone: poll failed: %s\n", + strerror (errno)); + } + break; + } + break; + } + } + else + ret = 0; + if(ret >= 0) + data_fd = accept (fd, 0, 0); close (fd); /* Get address of remote host */ @@ -2112,7 +2147,7 @@ process_request (Wire * w) DBG (DBG_MSG, "process_request: access to data port from %s\n", text_addr); - + if (strcmp (text_addr, remote_ip) != 0) { DBG (DBG_ERR, "process_request: however, only %s is authorized\n", @@ -2129,14 +2164,41 @@ process_request (Wire * w) { struct sockaddr_in sin; int len; + int ret; + struct pollfd fds[1]; + + fds->fd = fd; + fds->events = POLLIN; DBG (DBG_MSG, "process_request: waiting for data connection\n"); - data_fd = accept (fd, 0, 0); + if(data_connect_timeout) + { + while (1) + { + ret = poll (fds, 1, data_connect_timeout); + if (ret < 0) + { + if (errno == EINTR) + continue; + else + { + DBG (DBG_ERR, "run_standalone: poll failed: %s\n", strerror (errno)); + } + break; + } + break; + } + } + else + ret = 0; + if(ret >= 0) + data_fd = accept (fd, 0, 0); + close (fd); /* Get address of remote host */ len = sizeof (sin); - if (getpeername (data_fd, (struct sockaddr *) &sin, + if (getpeername (data_fd, (struct sockaddr *) &sin, (socklen_t *) &len) < 0) { DBG (DBG_ERR, "process_request: getpeername failed: %s\n", @@ -2147,13 +2209,13 @@ process_request (Wire * w) if (memcmp (&remote_address, &sin.sin_addr, sizeof (remote_address)) != 0) { - DBG (DBG_ERR, + DBG (DBG_ERR, "process_request: access to data port from %s\n", inet_ntoa (sin.sin_addr)); - DBG (DBG_ERR, + DBG (DBG_ERR, "process_request: however, only %s is authorized\n", inet_ntoa (remote_address)); - DBG (DBG_ERR, + DBG (DBG_ERR, "process_request: configuration problem or attack?\n"); close (data_fd); data_fd = -1; @@ -2320,7 +2382,7 @@ handle_connection (int fd) reset_watchdog (); if (process_request (&wire) < 0) break; - } + } } static void @@ -2735,6 +2797,26 @@ read_config (void) DBG (DBG_INFO, "read_config: data port range: %d - %d\n", data_port_lo, data_port_hi); } } + else if(strstr(config_line, "data_connect_timeout") != NULL) + { + optval = sanei_config_skip_whitespace (++optval); + if ((optval != NULL) && (*optval != '\0')) + { + val = strtol (optval, &endval, 10); + if (optval == endval) + { + DBG (DBG_ERR, "read_config: invalid value for data_connect_timeout\n"); + continue; + } + else if ((val < 0) || (val > 65535)) + { + DBG (DBG_ERR, "read_config: data_connect_timeout is invalid\n"); + continue; + } + data_connect_timeout = val; + DBG (DBG_INFO, "read_config: data connect timeout: %d\n", data_connect_timeout); + } + } } fclose (fp); DBG (DBG_INFO, "read_config: done reading config\n"); @@ -2964,93 +3046,129 @@ do_bindings (int *nfds, struct pollfd **fds) static void -run_standalone (char *user) +runas_user (char *user) { - struct pollfd *fds = NULL; - struct pollfd *fdp = NULL; - int nfds; - int fd = -1; - int i; - int ret; - uid_t runas_uid = 0; gid_t runas_gid = 0; struct passwd *pwent; gid_t *grplist = NULL; struct group *grp; int ngroups = 0; - FILE *pidfile; + int ret; - do_bindings (&nfds, &fds); + pwent = getpwnam(user); - if (run_mode != SANED_RUN_DEBUG) + if (pwent == NULL) { - if (user) - { - pwent = getpwnam(user); + DBG (DBG_ERR, "FATAL ERROR: user %s not found on system\n", user); + bail_out (1); + } - if (pwent == NULL) - { - DBG (DBG_ERR, "FATAL ERROR: user %s not found on system\n", user); - bail_out (1); - } + runas_uid = pwent->pw_uid; + runas_gid = pwent->pw_gid; - runas_uid = pwent->pw_uid; - runas_gid = pwent->pw_gid; + /* Get group list for runas_uid */ + grplist = (gid_t *)malloc(sizeof(gid_t)); - /* Get group list for runas_uid */ - grplist = (gid_t *)malloc(sizeof(gid_t)); + if (grplist == NULL) + { + DBG (DBG_ERR, "FATAL ERROR: cannot allocate memory for group list\n"); - if (grplist == NULL) - { - DBG (DBG_ERR, "FATAL ERROR: cannot allocate memory for group list\n"); + exit (1); + } - exit (1); - } + ngroups = 1; + grplist[0] = runas_gid; - ngroups = 1; - grplist[0] = runas_gid; + setgrent(); + while ((grp = getgrent()) != NULL) + { + int i = 0; - setgrent(); - while ((grp = getgrent()) != NULL) - { - int i = 0; + /* Already added current group */ + if (grp->gr_gid == runas_gid) + continue; - /* Already added current group */ - if (grp->gr_gid == runas_gid) - continue; + while (grp->gr_mem[i]) + { + if (strcmp(grp->gr_mem[i], user) == 0) + { + int need_to_add = 1, j; - while (grp->gr_mem[i]) + /* Make sure its not already in list */ + for (j = 0; j < ngroups; j++) { - if (strcmp(grp->gr_mem[i], user) == 0) - { - int need_to_add = 1, j; - - /* Make sure its not already in list */ - for (j = 0; j < ngroups; j++) - { - if (grp->gr_gid == grplist[i]) - need_to_add = 0; - } - if (need_to_add) - { - grplist = (gid_t *)realloc(grplist, - sizeof(gid_t)*ngroups+1); - if (grplist == NULL) - { - DBG (DBG_ERR, "FATAL ERROR: cannot reallocate memory for group list\n"); - - exit (1); - } - grplist[ngroups++] = grp->gr_gid; - } - } - i++; - } + if (grp->gr_gid == grplist[i]) + need_to_add = 0; + } + if (need_to_add) + { + grplist = (gid_t *)realloc(grplist, + sizeof(gid_t)*ngroups+1); + if (grplist == NULL) + { + DBG (DBG_ERR, "FATAL ERROR: cannot reallocate memory for group list\n"); + + exit (1); + } + grplist[ngroups++] = grp->gr_gid; + } } - endgrent(); + i++; + } + } + endgrent(); + + /* Drop privileges if requested */ + if (runas_uid > 0) + { + ret = setgroups(ngroups, grplist); + if (ret < 0) + { + DBG (DBG_ERR, "FATAL ERROR: could not set group list: %s\n", strerror(errno)); + + exit (1); + } + + free(grplist); + + ret = setegid (runas_gid); + if (ret < 0) + { + DBG (DBG_ERR, "FATAL ERROR: setegid to gid %d failed: %s\n", runas_gid, strerror (errno)); + + exit (1); + } + + ret = seteuid (runas_uid); + if (ret < 0) + { + DBG (DBG_ERR, "FATAL ERROR: seteuid to uid %d failed: %s\n", runas_uid, strerror (errno)); + + exit (1); } + DBG (DBG_WARN, "Dropped privileges to uid %d gid %d\n", runas_uid, runas_gid); + } +} + + +static void +run_standalone (char *user) +{ + struct pollfd *fds = NULL; + struct pollfd *fdp = NULL; + int nfds; + int fd = -1; + int i; + int ret; + + FILE *pidfile; + + do_bindings (&nfds, &fds); + + if (run_foreground == SANE_FALSE) + { DBG (DBG_MSG, "run_standalone: daemonizing now\n"); fd = open ("/dev/null", O_RDWR); @@ -3093,42 +3211,13 @@ run_standalone (char *user) setsid (); - /* Drop privileges if requested */ - if (runas_uid > 0) - { - ret = setgroups(ngroups, grplist); - if (ret < 0) - { - DBG (DBG_ERR, "FATAL ERROR: could not set group list: %s\n", strerror(errno)); - - exit (1); - } - - free(grplist); - - ret = setegid (runas_gid); - if (ret < 0) - { - DBG (DBG_ERR, "FATAL ERROR: setegid to gid %d failed: %s\n", runas_gid, strerror (errno)); - - exit (1); - } - - ret = seteuid (runas_uid); - if (ret < 0) - { - DBG (DBG_ERR, "FATAL ERROR: seteuid to uid %d failed: %s\n", runas_uid, strerror (errno)); - - exit (1); - } - - DBG (DBG_WARN, "Dropped privileges to uid %d gid %d\n", runas_uid, runas_gid); - } - signal(SIGINT, sig_int_term_handler); signal(SIGTERM, sig_int_term_handler); } + if (user) + runas_user(user); + #ifdef WITH_AVAHI DBG (DBG_INFO, "run_standalone: spawning Avahi process\n"); saned_avahi (fds, nfds); @@ -3187,13 +3276,13 @@ run_standalone (char *user) continue; } - if (run_mode == SANED_RUN_DEBUG) - break; /* We have the only connection we're going to handle */ - else - handle_client (fd); + handle_client (fd); + + if (run_once == SANE_TRUE) + break; /* We have handled the only connection we're going to handle */ } - if (run_mode == SANED_RUN_DEBUG) + if (run_once == SANE_TRUE) break; } @@ -3201,21 +3290,13 @@ run_standalone (char *user) close (fdp->fd); free (fds); - - if (run_mode == SANED_RUN_DEBUG) - { - if (fd > 0) - handle_connection (fd); - - bail_out(0); - } } static void run_inetd (char __sane_unused__ *sock) { - + int fd = -1; #ifdef HAVE_SYSTEMD @@ -3223,7 +3304,7 @@ run_inetd (char __sane_unused__ *sock) n = sd_listen_fds(0); - if (n > 1) + if (n > 1) { DBG (DBG_ERR, "run_inetd: Too many file descriptors (sockets) received from systemd!\n"); return; @@ -3236,7 +3317,7 @@ run_inetd (char __sane_unused__ *sock) } #endif - if (fd == -1) + if (fd == -1) { int dave_null; @@ -3299,12 +3380,14 @@ static void usage(char *me, int err) fprintf (stderr, "Usage: %s [OPTIONS]\n\n" " Options:\n\n" - " -a, --alone[=user] run standalone and fork in background as `user'\n" - " -d, --debug[=level] run foreground with output to stdout\n" - " and debug level `level' (default is 2)\n" - " -s, --syslog[=level] run foreground with output to syslog\n" - " and debug level `level' (default is 2)\n" - " -b, --bind=addr bind address `addr'\n" + " -a, --alone[=user] equal to `-l -D -u user'\n" + " -l, --listen run in standalone mode (listen for connection)\n" + " -u, --user=user run as `user'\n" + " -D, --daemonize run in background\n" + " -o, --once exit after first client disconnects\n" + " -d, --debug=level set debug level `level' (default is 2)\n" + " -e, --stderr output to stderr\n" + " -b, --bind=addr bind address `addr' (default all interfaces)\n" " -h, --help show this help message and exit\n", me); exit(err); @@ -3317,8 +3400,12 @@ static struct option long_options[] = /* These options set a flag. */ {"help", no_argument, 0, 'h'}, {"alone", optional_argument, 0, 'a'}, - {"debug", optional_argument, 0, 'd'}, - {"syslog", optional_argument, 0, 's'}, + {"listen", no_argument, 0, 'l'}, + {"user", required_argument, 0, 'u'}, + {"daemonize", no_argument, 0, 'D'}, + {"once", no_argument, 0, 'o'}, + {"debug", required_argument, 0, 'd'}, + {"stderr", no_argument, 0, 'e'}, {"bind", required_argument, 0, 'b'}, {0, 0, 0, 0 } }; @@ -3342,20 +3429,35 @@ main (int argc, char *argv[]) numchildren = 0; run_mode = SANED_RUN_INETD; + run_foreground = SANE_TRUE; + run_once = SANE_FALSE; - while((c = getopt_long(argc, argv,"ha::d::s::b:", long_options, &long_index )) != -1) + while((c = getopt_long(argc, argv,"ha::lu:Dod:eb:", long_options, &long_index )) != -1) { switch(c) { case 'a': run_mode = SANED_RUN_ALONE; + run_foreground = SANE_FALSE; + if (optarg) + user = optarg; + break; + case 'l': + run_mode = SANED_RUN_ALONE; + break; + case 'u': user = optarg; break; + case 'D': + run_foreground = SANE_FALSE; + break; + case 'o': + run_once = SANE_TRUE; + break; case 'd': + debug = atoi(optarg); + break; + case 'e': log_to_syslog = SANE_FALSE; - case 's': - run_mode = SANED_RUN_DEBUG; - if(optarg) - debug = atoi(optarg); break; case 'b': bind_addr = optarg; @@ -3405,7 +3507,7 @@ main (int argc, char *argv[]) DBG (DBG_WARN, "saned from %s ready\n", PACKAGE_STRING); } - if ((run_mode == SANED_RUN_ALONE) || (run_mode == SANED_RUN_DEBUG)) + if (run_mode == SANED_RUN_ALONE) { run_standalone(user); } diff --git a/frontend/scanimage.c b/frontend/scanimage.c index fe02750..6906f90 100644 --- a/frontend/scanimage.c +++ b/frontend/scanimage.c @@ -2,7 +2,7 @@ Uses the SANE library. Copyright (C) 2015 Rolf Bensch Copyright (C) 1996, 1997, 1998 Andreas Beck and David Mosberger - + Copyright (C) 1999 - 2009 by the SANE Project -- See AUTHORS and ChangeLog for details. @@ -93,6 +93,7 @@ static struct option basic_options[] = { {"help", no_argument, NULL, 'h'}, {"verbose", no_argument, NULL, 'v'}, {"progress", no_argument, NULL, 'p'}, + {"output-file", required_argument, NULL, 'o'}, {"test", no_argument, NULL, 'T'}, {"all-options", no_argument, NULL, 'A'}, {"version", no_argument, NULL, 'V'}, @@ -111,12 +112,13 @@ static struct option basic_options[] = { {0, 0, NULL, 0} }; -#define OUTPUT_PNM 0 -#define OUTPUT_TIFF 1 -#define OUTPUT_PNG 2 -#define OUTPUT_JPEG 3 +#define OUTPUT_UNKNOWN 0 +#define OUTPUT_PNM 1 +#define OUTPUT_TIFF 2 +#define OUTPUT_PNG 3 +#define OUTPUT_JPEG 4 -#define BASE_OPTSTRING "d:hi:Lf:B::nvVTAbp" +#define BASE_OPTSTRING "d:hi:Lf:o:B::nvVTAbp" #define STRIP_HEIGHT 256 /* # lines we increment image height */ static struct option *all_options; @@ -125,9 +127,10 @@ static int *option_number; static SANE_Handle device; static int verbose; static int progress = 0; +static const char* output_file = NULL; static int test; static int all; -static int output_format = OUTPUT_PNM; +static int output_format = OUTPUT_UNKNOWN; static int help; static int dont_scan = 0; static const char *prog_name; @@ -403,7 +406,7 @@ print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *o }*/ /* if one of these three is not set, option is useless, skip it */ - if(!(opt->cap & + if(!(opt->cap & (SANE_CAP_SOFT_SELECT | SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT) )){ return; @@ -462,7 +465,7 @@ print_option (SANE_Device * device, int opt_num, const SANE_Option_Descriptor *o if (!strcmp (opt->name, "x")) { printf ("%d..%d", - opt->constraint.range->min, + opt->constraint.range->min, opt->constraint.range->max - tl_x); } else if (!strcmp (opt->name, "y")) @@ -1011,7 +1014,7 @@ set_option (SANE_Handle device, int optnum, void *valuep) prog_name, opt->name); return; } - + if (opt->size == sizeof (SANE_Word) && opt->type != SANE_TYPE_STRING) orig = *(SANE_Word *) valuep; @@ -1483,7 +1486,7 @@ scan_it (FILE *ofp) offset = parm.format - SANE_FRAME_RED; image.x = image.y = 0; } - hundred_percent = parm.bytes_per_line * parm.lines + hundred_percent = parm.bytes_per_line * parm.lines * ((parm.format == SANE_FRAME_RGB || parm.format == SANE_FRAME_GRAY) ? 1:3); while (1) @@ -1968,6 +1971,43 @@ static void print_options(SANE_Device * device, SANE_Int num_dev_options, SANE_B fputc ('\n', stdout); } +static int guess_output_format(const char* output_file) +{ + if (output_file == NULL) + { + fprintf(stderr, "Output format is not set, using pnm as a default.\n"); + return OUTPUT_PNM; + } + + // if the user passes us a path with a known extension then he won't be surprised if we figure + // out correct --format option. No warning is necessary in that case. + const char* extension = strrchr(output_file, '.'); + if (extension != NULL) + { + struct { + const char* extension; + int output_format; + } formats[] = { + { ".pnm", OUTPUT_PNM }, + { ".png", OUTPUT_PNG }, + { ".jpg", OUTPUT_JPEG }, + { ".jpeg", OUTPUT_JPEG }, + { ".tiff", OUTPUT_TIFF }, + { ".tif", OUTPUT_TIFF } + }; + for (unsigned i = 0; i < sizeof(formats) / sizeof(formats[0]); ++i) + { + if (strcmp(extension, formats[i].extension) == 0) + return formats[i].output_format; + } + } + + // it would be very confusing if user makes a typo in the filename and the output format changes. + // This is most likely not what the user wanted. + fprintf(stderr, "Could not guess output format from the given path and no --format given.\n"); + exit(1); +} + int main (int argc, char **argv) { @@ -2033,6 +2073,9 @@ main (int argc, char **argv) case 'p': progress = 1; break; + case 'o': + output_file = optarg; + break; case 'B': if (optarg) buffer_size = 1024 * atoi(optarg); @@ -2088,8 +2131,23 @@ main (int argc, char **argv) exit(1); #endif } - else - output_format = OUTPUT_PNM; + else if (strcmp (optarg, "pnm") == 0) + { + output_format = OUTPUT_PNM; + } + else + { + fprintf(stderr, "Unknown output image format '%s'.\n", optarg); + fprintf(stderr, "Supported formats: pnm, tiff"); +#ifdef HAVE_LIBPNG + fprintf(stderr, ", png"); +#endif +#ifdef HAVE_LIBJPEG + fprintf(stderr, ", jpeg"); +#endif + fprintf(stderr, ".\n"); + exit(1); + } break; case OPTION_MD5: accept_only_md5_auth = 1; @@ -2235,7 +2293,8 @@ Parameters are separated by a blank from single-character options (e.g.\n\ %%m (model), %%t (type), %%i (index number), and\n\ %%n (newline)\n\ -b, --batch[=FORMAT] working in batch mode, FORMAT is `out%%d.pnm' `out%%d.tif'\n\ - `out%%d.png' or `out%%d.jpg' by default depending on --format\n"); + `out%%d.png' or `out%%d.jpg' by default depending on --format\n\ + This option is incompatible with --output-file."); printf ("\ --batch-start=# page number to start naming files with\n\ --batch-count=# how many pages to scan in batch mode\n\ @@ -2247,6 +2306,8 @@ Parameters are separated by a blank from single-character options (e.g.\n\ printf ("\ --accept-md5-only only accept authorization requests using md5\n\ -p, --progress print progress messages\n\ +-o, --output-file=PATH save output to the given file instead of stdout.\n\ + This option is incompatible with --batch.\n\ -n, --dont-scan only set options, don't actually scan\n\ -T, --test test backend thoroughly\n\ -A, --all-options list all available backend options\n\ @@ -2257,6 +2318,15 @@ Parameters are separated by a blank from single-character options (e.g.\n\ -V, --version print version information\n"); } + if (batch && output_file != NULL) + { + fprintf(stderr, "--batch and --output-file can't be used together.\n"); + exit(1); + } + + if (output_format == OUTPUT_UNKNOWN) + output_format = guess_output_format(output_file); + if (!devname) { /* If no device name was specified explicitly, we look at the @@ -2389,6 +2459,7 @@ Parameters are separated by a blank from single-character options (e.g.\n\ case 'd': case 'h': case 'p': + case 'o': case 'v': case 'V': case 'T': @@ -2535,7 +2606,19 @@ List of available devices:", prog_name); } if (!batch) - ofp = stdout; + { + ofp = stdout; + if (output_file != NULL) + { + ofp = fopen(output_file, "w"); + if (ofp == NULL) + { + fprintf(stderr, "%s: could not open input file '%s', " + "exiting\n", prog_name, output_file); + scanimage_exit(1); + } + } + } if (batch) { @@ -2662,6 +2745,14 @@ List of available devices:", prog_name); } } } + else + { + if (output_file && ofp) + { + fclose(ofp); + ofp = NULL; + } + } break; default: if (batch) @@ -2673,6 +2764,15 @@ List of available devices:", prog_name); } unlink (part_path); } + else + { + if (output_file && ofp) + { + fclose(ofp); + ofp = NULL; + } + unlink (output_file); + } break; } /* switch */ n += batch_increment; diff --git a/frontend/test.c b/frontend/test.c index df06751..3b1c4ae 100644 --- a/frontend/test.c +++ b/frontend/test.c @@ -16,9 +16,9 @@ along with sane; see the file COPYING. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - This file implements a simple SANE frontend (well it rather is a - transport layer, but seen from libsane it is a frontend) which acts - as a NETSANE server. The NETSANE specifications should have come + This file implements a simple SANE frontend (well it rather is a + transport layer, but seen from libsane it is a frontend) which acts + as a NETSANE server. The NETSANE specifications should have come with this package. Feel free to enhance this program ! It needs extension especially regarding crypto-support and authentication. diff --git a/frontend/tstbackend.c b/frontend/tstbackend.c index 82c54dc..37ba660 100644 --- a/frontend/tstbackend.c +++ b/frontend/tstbackend.c @@ -1,9 +1,9 @@ -/* +/* tstbackend -- backend test utility Uses the SANE library. Copyright (C) 2002 Frank Zago (sane at zago dot net) - Copyright (C) 2013 Stéphane Voltz : sane_get_devices test + Copyright (C) 2013 Stéphane Voltz : sane_get_devices test This file is part of the SANE package. @@ -85,15 +85,15 @@ int verbose_level; static void display_stats(void) { #ifdef HAVE_LONG_LONG - printf("warnings: %d error: %d checks: %lld\n", + printf("warnings: %d error: %d checks: %lld\n", message_number_wrn, message_number_err, checks_done); #else - printf("warnings: %d error: %d checks: %ld\n", + printf("warnings: %d error: %d checks: %ld\n", message_number_wrn, message_number_err, checks_done); #endif } -/* +/* * If the condition is false, display a message with some headers * depending on the level. * @@ -109,8 +109,8 @@ static int check(enum message_level level, int condition, const char *format, .. va_list args; if (level != MSG && level != INF) checks_done ++; - - if (condition != 0) + + if (condition != 0) return condition; va_start(args, format); @@ -135,10 +135,10 @@ static int check(enum message_level level, int condition, const char *format, .. case FATAL: /* fatal error */ printf("FATAL ERROR : %s\n", str); message_number_err ++; - break; + break; case BUG: /* bug in tstbackend */ printf("tstbackend BUG : %s\n", str); - break; + break; } if (level == FATAL || level == BUG) { @@ -210,14 +210,14 @@ static void guards_check(void *ptr, size_t size) /*--------------------------------------------------------------------------*/ -static void +static void test_parameters (SANE_Device * device, SANE_Parameters *params) { SANE_Status status; SANE_Parameters p; status = sane_get_parameters (device, &p); - check(FATAL, (status == SANE_STATUS_GOOD), + check(FATAL, (status == SANE_STATUS_GOOD), "cannot get the parameters (error %s)", sane_strstatus(status)); check(FATAL, ((p.format == SANE_FRAME_GRAY) || @@ -227,7 +227,7 @@ test_parameters (SANE_Device * device, SANE_Parameters *params) (p.format == SANE_FRAME_BLUE)), "parameter format is not a known SANE_FRAME_* (%d)", p.format); - check(FATAL, ((p.last_frame == SANE_FALSE) || + check(FATAL, ((p.last_frame == SANE_FALSE) || (p.last_frame == SANE_TRUE)), "parameter last_frame is neither SANE_FALSE or SANE_TRUE (%d)", p.last_frame); @@ -243,7 +243,7 @@ test_parameters (SANE_Device * device, SANE_Parameters *params) /* Try to set every option in a word list. */ static void -test_options_word_list (SANE_Device * device, int option_num, +test_options_word_list (SANE_Device * device, int option_num, const SANE_Option_Descriptor *opt, int can_do_recursive) { @@ -252,24 +252,24 @@ test_options_word_list (SANE_Device * device, int option_num, SANE_Int val_int; SANE_Int info; - check(FATAL, (opt->type == SANE_TYPE_INT || + check(FATAL, (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED), "type must be SANE_TYPE_INT or SANE_TYPE_FIXED (%d)", opt->type); if (!SANE_OPTION_IS_SETTABLE(opt->cap)) return; for (i=1; iconstraint.word_list[0]; i++) { - + info = 0x1010; /* garbage */ val_int = opt->constraint.word_list[i]; - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, &val_int, &info); - + check(FATAL, (status == SANE_STATUS_GOOD), "cannot set a settable option (status=%s)", sane_strstatus(status)); - check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS | + check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS)) == 0), "sane_control_option set an invalid info (%d)", info); @@ -281,8 +281,8 @@ test_options_word_list (SANE_Device * device, int option_num, } /* The option might have become inactive or unsettable. Skip it. */ - if (!SANE_OPTION_IS_ACTIVE(opt->cap) || - !SANE_OPTION_IS_SETTABLE(opt->cap)) + if (!SANE_OPTION_IS_ACTIVE(opt->cap) || + !SANE_OPTION_IS_SETTABLE(opt->cap)) return; } @@ -290,7 +290,7 @@ test_options_word_list (SANE_Device * device, int option_num, /* Try to set every option in a string list. */ static void -test_options_string_list (SANE_Device * device, int option_num, +test_options_string_list (SANE_Device * device, int option_num, const SANE_Option_Descriptor *opt, int can_do_recursive) { @@ -314,13 +314,13 @@ test_options_string_list (SANE_Device * device, int option_num, val_string, opt->size); info = 0xE1000; /* garbage */ - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, val_string, &info); check(FATAL, (status == SANE_STATUS_GOOD), "cannot set a settable option (status=%s)", sane_strstatus(status)); - check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS | + check(WRN, ((info & ~(SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS)) == 0), "sane_control_option set an invalid info (%d)", info); @@ -334,8 +334,8 @@ test_options_string_list (SANE_Device * device, int option_num, } /* The option might have become inactive or unsettable. Skip it. */ - if (!SANE_OPTION_IS_ACTIVE(opt->cap) || - !SANE_OPTION_IS_SETTABLE(opt->cap)) + if (!SANE_OPTION_IS_ACTIVE(opt->cap) || + !SANE_OPTION_IS_SETTABLE(opt->cap)) return; } } @@ -352,8 +352,8 @@ test_options (SANE_Device * device, int can_do_recursive) void *optval; /* value for the option */ size_t optsize; /* size of the optval buffer */ - /* - * Test option 0 + /* + * Test option 0 */ opt = sane_get_option_descriptor (device, 0); check(FATAL, (opt != NULL), @@ -374,7 +374,7 @@ test_options (SANE_Device * device, int can_do_recursive) check(WRN, (status != SANE_STATUS_GOOD), "the option 0 value can be set"); - /* + /* * Test all options */ option_num = 0; @@ -454,7 +454,7 @@ test_options (SANE_Device * device, int can_do_recursive) check(WRN, (opt->constraint_type == SANE_CONSTRAINT_NONE), "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type); break; - + case SANE_TYPE_INT: case SANE_TYPE_FIXED: check(WRN, (opt->size > 0 && (opt->size % sizeof(SANE_Word) == 0)), @@ -467,7 +467,7 @@ test_options (SANE_Device * device, int can_do_recursive) "invalid constraint type for option [%d, %s] (%d)", option_num, opt->name, opt->constraint_type); break; - case SANE_TYPE_STRING: + case SANE_TYPE_STRING: check(WRN, (opt->size >= 1), "size of option [%d, %s] must be at least 1 for the NUL terminator", option_num, opt->name); check(INF, (opt->unit == SANE_UNIT_NONE), @@ -479,7 +479,7 @@ test_options (SANE_Device * device, int can_do_recursive) optsize = opt->size; break; - case SANE_TYPE_BUTTON: + case SANE_TYPE_BUTTON: case SANE_TYPE_GROUP: check(INF, (opt->unit == SANE_UNIT_NONE), "option [%d, %s], unit is not SANE_UNIT_NONE", option_num, opt->name); @@ -491,11 +491,11 @@ test_options (SANE_Device * device, int can_do_recursive) default: check(ERR, 0, - "invalid type %d for option %s", + "invalid type %d for option %s", opt->type, opt->name); break; } - + if (optval) { /* This is an option with a value */ @@ -505,7 +505,7 @@ test_options (SANE_Device * device, int can_do_recursive) * consider that an inactive option shouldn't be read by a * frontend because its value is meaningless. I think * that, in that case, SANE_STATUS_INVAL is an appropriate - * return. + * return. */ guards_set(optval, optsize); status = sane_control_option (device, option_num, @@ -522,7 +522,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* set with NULL info */ guards_set(optval, optsize); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, optval, NULL); guards_check(optval, optsize); if (SANE_OPTION_IS_SETTABLE (opt->cap) && SANE_OPTION_IS_ACTIVE (opt->cap)) { @@ -531,13 +531,13 @@ test_options (SANE_Device * device, int can_do_recursive) } else { check(ERR, (status == SANE_STATUS_INVAL), "was able to set option [%d, %s] value, although it is not active or settable", option_num, opt->name); - } - + } + /* Get with invalid info. Since if is a get, info should be either * ignored or set to 0. */ info = 0xdeadbeef; guards_set(optval, optsize); - status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, + status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, optval, &info); guards_check(optval, optsize); if (SANE_OPTION_IS_GETTABLE (opt->cap)) { @@ -549,19 +549,19 @@ test_options (SANE_Device * device, int can_do_recursive) } check(ERR, ((info == (SANE_Int)0xdeadbeef) || (info == 0)), "when getting option [%d, %s], info was set to %x", option_num, opt->name, info); - + /* Set with invalid info. Info should be reset by the backend. */ info = 0x10000; guards_set(optval, optsize); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, optval, &info); guards_check(optval, optsize); if (SANE_OPTION_IS_SETTABLE (opt->cap) && SANE_OPTION_IS_ACTIVE (opt->cap)) { check(ERR, (status == SANE_STATUS_GOOD), "cannot set option [%d, %s] value, although it is active and settable (%s)", option_num, opt->name, sane_strstatus(status)); - check(ERR, ((info & ~(SANE_INFO_INEXACT | - SANE_INFO_RELOAD_OPTIONS | + check(ERR, ((info & ~(SANE_INFO_INEXACT | + SANE_INFO_RELOAD_OPTIONS | SANE_INFO_RELOAD_PARAMS)) == 0), "sane_control_option set some wrong bit in info (%d)", info); @@ -575,10 +575,10 @@ test_options (SANE_Device * device, int can_do_recursive) /* Ask the backend to set the option automatically. */ guards_set(optval, optsize); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_AUTO, optval, &info); guards_check(optval, optsize); - if (SANE_OPTION_IS_SETTABLE (opt->cap) && + if (SANE_OPTION_IS_SETTABLE (opt->cap) && SANE_OPTION_IS_ACTIVE (opt->cap) && (opt->cap & SANE_CAP_AUTOMATIC)) { check(ERR, (status == SANE_STATUS_GOOD), @@ -594,7 +594,7 @@ test_options (SANE_Device * device, int can_do_recursive) if (optval) { guards_free(optval); - optval = NULL; + optval = NULL; } /* Some capabilities checks. */ @@ -605,18 +605,18 @@ test_options (SANE_Device * device, int can_do_recursive) check(ERR, ((opt->cap & SANE_CAP_SOFT_DETECT) != 0), "option [%d, %s], SANE_CAP_SOFT_DETECT must be set if SANE_CAP_SOFT_SELECT is set", option_num, opt->name); } - if ((opt->cap & (SANE_CAP_SOFT_SELECT | - SANE_CAP_HARD_SELECT | + if ((opt->cap & (SANE_CAP_SOFT_SELECT | + SANE_CAP_HARD_SELECT | SANE_CAP_SOFT_DETECT)) == SANE_CAP_SOFT_DETECT) { check(ERR, (!SANE_OPTION_IS_SETTABLE (opt->cap)), "option [%d, %s], must not be settable", option_num, opt->name); } - + if (!SANE_OPTION_IS_SETTABLE (opt->cap)) { /* Unsettable option. Ignore the rest of the test. */ continue; } - + /* Check that will sane_control_option copy the string * parameter and not just store a pointer to it. */ if (opt->type == SANE_TYPE_STRING) { @@ -624,7 +624,7 @@ test_options (SANE_Device * device, int can_do_recursive) char *optstr; optstr = guards_malloc(opt->size); - val_string2 = guards_malloc(opt->size); + val_string2 = guards_malloc(opt->size); /* Poison the current value. */ strncpy(optstr, "-pOiSoN-", opt->size-1); @@ -632,7 +632,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* Get the value */ guards_set(optstr, opt->size); - status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, + status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, optstr, NULL); guards_check(optstr, opt->size); check(FATAL, (status == SANE_STATUS_GOOD), @@ -642,7 +642,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* Set the value */ guards_set(optstr, opt->size); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, optstr, NULL); guards_check(optstr, opt->size); check(ERR, (status == SANE_STATUS_GOOD), @@ -653,13 +653,13 @@ test_options (SANE_Device * device, int can_do_recursive) optstr[opt->size-1] = 0; /* Read again the value and compare. */ - guards_set(val_string2, opt->size); - status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, + guards_set(val_string2, opt->size); + status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, val_string2, NULL); guards_check(val_string2, opt->size); check(ERR, (status == SANE_STATUS_GOOD), "cannot get option [%d, %s] value", option_num, opt->name); - + check(FATAL, (strcmp(optstr, val_string2) != 0), "sane_control_option did not copy the string parameter for option [%d, %s]", option_num, opt->name); @@ -671,8 +671,8 @@ test_options (SANE_Device * device, int can_do_recursive) if (opt->type == SANE_TYPE_BOOL) { SANE_Bool org_v; SANE_Bool v; - - status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, + + status = sane_control_option (device, option_num, SANE_ACTION_GET_VALUE, &org_v, &info); check(ERR, (status == SANE_STATUS_GOOD), "cannot get boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status)); @@ -686,12 +686,12 @@ test_options (SANE_Device * device, int can_do_recursive) break; default: check(ERR, 0, - "invalid boolean value %d for option [%d, %s]", + "invalid boolean value %d for option [%d, %s]", org_v, option_num, opt->name); } - + /* Set the opposite of the current value. */ - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, &v, &info); check(ERR, (status == SANE_STATUS_GOOD), "cannot set boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status)); @@ -704,7 +704,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* Set the initial value. */ v = org_v; - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, &v, &info); check(ERR, (status == SANE_STATUS_GOOD), "cannot set boolean option [%d, %s] value (%s)", option_num, opt->name, sane_strstatus(status)); @@ -713,22 +713,22 @@ test_options (SANE_Device * device, int can_do_recursive) if (info & SANE_INFO_RELOAD_PARAMS) { test_parameters(device, NULL); - } + } } - + /* Try to set an invalid option. */ switch(opt->type) { case SANE_TYPE_BOOL: { SANE_Word v; /* should be SANE_Bool instead */ - + v = -1; /* invalid value. must be SANE_FALSE or SANE_TRUE */ - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, &v, NULL); check(ERR, (status != SANE_STATUS_GOOD), "was able to set an invalid value for boolean option [%d, %s]", option_num, opt->name); v = 2; /* invalid value. must be SANE_FALSE or SANE_TRUE */ - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, &v, NULL); check(ERR, (status != SANE_STATUS_GOOD), "was able to set an invalid value for boolean option [%d, %s]", option_num, opt->name); @@ -750,7 +750,7 @@ test_options (SANE_Device * device, int can_do_recursive) v[i] = opt->constraint.range->min - 1; /* invalid range */ guards_set(v, opt->size); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, v, &info); guards_check(v, opt->size); check(ERR, (status == SANE_STATUS_GOOD && (info & SANE_INFO_INEXACT) ), @@ -758,7 +758,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* Set the corrected value. */ guards_set(v, opt->size); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, v, &info); guards_check(v, opt->size); check(ERR, (status == SANE_STATUS_GOOD && !(info & SANE_INFO_INEXACT) ), @@ -769,7 +769,7 @@ test_options (SANE_Device * device, int can_do_recursive) v[i] = opt->constraint.range->max + 1; /* invalid range */ guards_set(v, opt->size); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, v, &info); guards_check(v, opt->size); check(ERR, (status == SANE_STATUS_GOOD && (info & SANE_INFO_INEXACT) ), @@ -777,7 +777,7 @@ test_options (SANE_Device * device, int can_do_recursive) /* Set the corrected value. */ guards_set(v, opt->size); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, v, &info); guards_check(v, opt->size); check(ERR, (status == SANE_STATUS_GOOD && !(info & SANE_INFO_INEXACT) ), @@ -791,15 +791,15 @@ test_options (SANE_Device * device, int can_do_recursive) default: break; } - + /* TODO: button */ - - /* + + /* * Here starts all the recursive stuff. After the test, it is * possible that the value is not settable nor active - * anymore. + * anymore. */ - + /* Try to set every option in a list */ switch(opt->constraint_type) { case SANE_CONSTRAINT_WORD_LIST: @@ -813,12 +813,12 @@ test_options (SANE_Device * device, int can_do_recursive) "no constraint list for option [%d, %s]", option_num, opt->name); test_options_string_list (device, option_num, opt, can_do_recursive); break; - + case SANE_CONSTRAINT_RANGE: check(FATAL, (opt->constraint.range != NULL), "no constraint range for option [%d, %s]", option_num, opt->name); check(FATAL, (opt->constraint.range->max >= opt->constraint.range->min), - "incorrect range for option [%d, %s] (min=%d > max=%d)", + "incorrect range for option [%d, %s] (min=%d > max=%d)", option_num, opt->name, opt->constraint.range->min, opt->constraint.range->max); /* Recurse. */ if (can_do_recursive) { @@ -838,7 +838,7 @@ test_options (SANE_Device * device, int can_do_recursive) } /* End of the test for that option. */ - } + } /* test random non-existing options. */ opt = sane_get_option_descriptor (device, -1); @@ -852,7 +852,7 @@ test_options (SANE_Device * device, int can_do_recursive) opt = sane_get_option_descriptor (device, num_dev_options+2); check(ERR, (opt == NULL), "was able to get option descriptor for option %d", num_dev_options+2); - + opt = sane_get_option_descriptor (device, num_dev_options+50); check(ERR, (opt == NULL), "was able to get option descriptor for option %d", num_dev_options+50); @@ -863,8 +863,8 @@ static const SANE_Option_Descriptor *get_optdesc_by_name(SANE_Handle device, con { const SANE_Option_Descriptor *opt; SANE_Int num_dev_options; - SANE_Status status; - + SANE_Status status; + /* Get the number of options. */ status = sane_control_option (device, 0, SANE_ACTION_GET_VALUE, &num_dev_options, 0); check(FATAL, (status == SANE_STATUS_GOOD), @@ -876,7 +876,7 @@ static const SANE_Option_Descriptor *get_optdesc_by_name(SANE_Handle device, con opt = sane_get_option_descriptor (device, *option_num); check(FATAL, (opt != NULL), "cannot get option descriptor for option %d", *option_num); - + if (opt->name && strcmp(opt->name, name) == 0) { return(opt); } @@ -886,10 +886,10 @@ static const SANE_Option_Descriptor *get_optdesc_by_name(SANE_Handle device, con /* Set the first value for an option. That equates to the minimum for a * range or the first element in a list. */ -static void set_min_value(SANE_Handle device, int option_num, +static void set_min_value(SANE_Handle device, int option_num, const SANE_Option_Descriptor *opt) { - SANE_Status status; + SANE_Status status; SANE_String val_string; SANE_Int val_int; int rc; @@ -915,7 +915,7 @@ static void set_min_value(SANE_Handle device, int option_num, if (!rc) return; val_string = strdup(opt->constraint.string_list[0]); assert(val_string); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, val_string, NULL); check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status)); @@ -929,7 +929,7 @@ static void set_min_value(SANE_Handle device, int option_num, check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status)); break; - + default: abort(); } @@ -937,10 +937,10 @@ static void set_min_value(SANE_Handle device, int option_num, /* Set the last value for an option. That equates to the maximum for a * range or the last element in a list. */ -static void set_max_value(SANE_Handle device, int option_num, +static void set_max_value(SANE_Handle device, int option_num, const SANE_Option_Descriptor *opt) { - SANE_Status status; + SANE_Status status; SANE_String val_string; SANE_Int val_int; int i; @@ -968,7 +968,7 @@ static void set_max_value(SANE_Handle device, int option_num, for (i=1; opt->constraint.string_list[i] != NULL; i++); val_string = strdup(opt->constraint.string_list[i-1]); assert(val_string); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, val_string, NULL); check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status)); @@ -982,17 +982,17 @@ static void set_max_value(SANE_Handle device, int option_num, check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status)); break; - + default: abort(); } } /* Set a random value for an option amongst the possible values. */ -static void set_random_value(SANE_Handle device, int option_num, +static void set_random_value(SANE_Handle device, int option_num, const SANE_Option_Descriptor *opt) { - SANE_Status status; + SANE_Status status; SANE_String val_string; SANE_Int val_int; int i; @@ -1022,7 +1022,7 @@ static void set_random_value(SANE_Handle device, int option_num, i = rand() % i; val_string = strdup(opt->constraint.string_list[0]); assert(val_string); - status = sane_control_option (device, option_num, + status = sane_control_option (device, option_num, SANE_ACTION_SET_VALUE, val_string, NULL); check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to [%s] (%s)", opt->name, val_string, sane_strstatus(status)); @@ -1038,7 +1038,7 @@ static void set_random_value(SANE_Handle device, int option_num, check(ERR, (status == SANE_STATUS_GOOD), "cannot set option %s to %d (%s)", opt->name, val_int, sane_strstatus(status)); break; - + default: abort(); } @@ -1053,18 +1053,18 @@ static char *get_option_value(SANE_Handle device, const char *option_name) void *optval; /* value for the option */ int optnum; static char str[100]; - SANE_Status status; + SANE_Status status; opt = get_optdesc_by_name(device, option_name, &optnum); if (opt) { - + optval = guards_malloc(opt->size); status = sane_control_option (device, optnum, SANE_ACTION_GET_VALUE, optval, NULL); - + if (status == SANE_STATUS_GOOD) { switch(opt->type) { - + case SANE_TYPE_BOOL: if (*(SANE_Word*) optval == SANE_FALSE) { strcpy(str, "FALSE"); @@ -1072,22 +1072,22 @@ static char *get_option_value(SANE_Handle device, const char *option_name) strcpy(str, "TRUE"); } break; - + case SANE_TYPE_INT: sprintf(str, "%d", *(SANE_Word*) optval); break; - + case SANE_TYPE_FIXED: { int i; i = SANE_UNFIX(*(SANE_Word*) optval); sprintf(str, "%d", i); } break; - + case SANE_TYPE_STRING: strcpy(str, optval); break; - + default: str[0] = 0; } @@ -1113,7 +1113,7 @@ static char *display_scan_parameters(SANE_Handle device) char *p = str; *p = 0; - + p += sprintf(p, "scan mode=[%s] ", get_option_value(device, SANE_NAME_SCAN_MODE)); p += sprintf(p, "resolution=[%s] ", get_option_value(device, SANE_NAME_SCAN_RESOLUTION)); @@ -1129,7 +1129,7 @@ static char *display_scan_parameters(SANE_Handle device) static void test_scan(SANE_Handle device) { const SANE_Option_Descriptor *opt; - SANE_Status status; + SANE_Status status; int option_num; SANE_Int val_int; unsigned char *image = NULL; @@ -1140,7 +1140,7 @@ static void test_scan(SANE_Handle device) int rc; int fd; - /* Set the largest scan possible. + /* Set the largest scan possible. * * For that test, the corner * position must exists and be SANE_CONSTRAINT_RANGE (this is not @@ -1169,17 +1169,17 @@ static void test_scan(SANE_Handle device) /* Try to set the I/O mode outside of a scan. */ status = sane_set_io_mode (device, SANE_FALSE); check(ERR, (status == SANE_STATUS_INVAL), - "it is possible to sane_set_io_mode outside of a scan"); + "it is possible to sane_set_io_mode outside of a scan"); status = sane_set_io_mode (device, SANE_TRUE); check(ERR, (status == SANE_STATUS_INVAL || status == SANE_STATUS_UNSUPPORTED), - "it is possible to sane_set_io_mode outside of a scan"); + "it is possible to sane_set_io_mode outside of a scan"); /* Test sane_get_select_fd outside of a scan. */ status = sane_get_select_fd(device, &fd); - check(ERR, (status == SANE_STATUS_INVAL || + check(ERR, (status == SANE_STATUS_INVAL || status == SANE_STATUS_UNSUPPORTED), - "sane_get_select_fd outside of a scan returned an invalid status (%s)", + "sane_get_select_fd outside of a scan returned an invalid status (%s)", sane_strstatus (status)); if (test_level > 2) { @@ -1197,11 +1197,11 @@ static void test_scan(SANE_Handle device) check(ERR, (status == SANE_STATUS_GOOD), "sane_set_io_mode with SANE_FALSE must return SANE_STATUS_GOOD"); - /* test sane_set_io_mode with SANE_TRUE. */ + /* test sane_set_io_mode with SANE_TRUE. */ status = sane_set_io_mode (device, SANE_TRUE); - check(ERR, (status == SANE_STATUS_GOOD || + check(ERR, (status == SANE_STATUS_GOOD || status == SANE_STATUS_UNSUPPORTED), - "sane_set_io_mode with SANE_TRUE returned an invalid status (%s)", + "sane_set_io_mode with SANE_TRUE returned an invalid status (%s)", sane_strstatus (status)); /* Put the backend back into blocking mode. */ @@ -1212,9 +1212,9 @@ static void test_scan(SANE_Handle device) /* Test sane_get_select_fd */ fd = 0x76575; /* won't exists */ status = sane_get_select_fd(device, &fd); - check(ERR, (status == SANE_STATUS_GOOD || + check(ERR, (status == SANE_STATUS_GOOD || status == SANE_STATUS_UNSUPPORTED), - "sane_get_select_fd returned an invalid status (%s)", + "sane_get_select_fd returned an invalid status (%s)", sane_strstatus (status)); if (status == SANE_STATUS_GOOD) { check(ERR, (fd != 0x76575), @@ -1222,13 +1222,13 @@ static void test_scan(SANE_Handle device) check(ERR, (fd >= 0), "sane_get_select_fd returned an invalid fd"); } - + /* Check that it is not possible to set an option. It is probably * a requirement stated indirectly in the section 4.4 on code - * flow. + * flow. */ - status = sane_control_option (device, option_num, - SANE_ACTION_SET_VALUE, + status = sane_control_option (device, option_num, + SANE_ACTION_SET_VALUE, &val_int , NULL); check(WRN, (status != SANE_STATUS_GOOD), "it is possible to set a value during a scan"); @@ -1236,7 +1236,7 @@ static void test_scan(SANE_Handle device) test_parameters(device, ¶ms); if (params.bytes_per_line != 0 && params.lines != 0) { - + to_read = params.bytes_per_line * params.lines; while(SANE_TRUE) { len = 76457645; /* garbage */ @@ -1288,8 +1288,8 @@ static void test_scan(SANE_Handle device) "it is possible to sane_read outside a scan"); - /* - * Do a partial scan + /* + * Do a partial scan */ check(MSG, 0, "TEST: partial scan - %s", display_scan_parameters(device)); @@ -1301,7 +1301,7 @@ static void test_scan(SANE_Handle device) test_parameters(device, ¶ms); if (params.bytes_per_line != 0 && params.lines != 0) { - + len = 10; guards_set(image, 1); @@ -1311,12 +1311,12 @@ static void test_scan(SANE_Handle device) check(ERR, (len == 1), "sane_read() didn't return 1 byte as requested"); } - + sane_cancel(device); - /* - * Do a scan, reading random length. + /* + * Do a scan, reading random length. */ check(MSG, 0, "TEST: scan random length - %s", display_scan_parameters(device)); @@ -1336,8 +1336,8 @@ static void test_scan(SANE_Handle device) if (!rc) goto the_end; /* Check that it is not possible to set an option. */ - status = sane_control_option (device, option_num, - SANE_ACTION_SET_VALUE, + status = sane_control_option (device, option_num, + SANE_ACTION_SET_VALUE, &val_int , NULL); check(WRN, (status != SANE_STATUS_GOOD), "it is possible to set a value during a scan"); @@ -1345,10 +1345,10 @@ static void test_scan(SANE_Handle device) test_parameters(device, ¶ms); if (params.bytes_per_line != 0 && params.lines != 0) { - + to_read = params.bytes_per_line * params.lines; srandom(time(NULL)); - + while (SANE_TRUE) { ask_len = rand() & 0x7ffff; /* 0 to 512K-1 */ @@ -1387,7 +1387,7 @@ static void test_scan(SANE_Handle device) if (!rc) { break; } - + to_read -= len; } @@ -1422,7 +1422,7 @@ static void test_scan(SANE_Handle device) test_parameters(device, ¶ms); if (params.bytes_per_line != 0 && params.lines != 0) { - + to_read = params.bytes_per_line * params.lines; while(SANE_TRUE) { ask_len = IMAGE_SIZE; @@ -1481,7 +1481,7 @@ static void test_scans(SANE_Device * device) { const SANE_Option_Descriptor *scan_mode_opt; const SANE_Option_Descriptor *resolution_mode_opt; - SANE_Status status; + SANE_Status status; int scan_mode_optnum; int resolution_mode_optnum; SANE_String val_string; @@ -1519,27 +1519,27 @@ static void test_scans(SANE_Device * device) if (scan_mode_opt) { /* Do several scans, with several resolution. */ for (i=0; scan_mode_opt->constraint.string_list[i] != NULL; i++) { - + val_string = strdup(scan_mode_opt->constraint.string_list[i]); assert(val_string); - - status = sane_control_option (device, scan_mode_optnum, + + status = sane_control_option (device, scan_mode_optnum, SANE_ACTION_SET_VALUE, val_string, NULL); check(FATAL, (status == SANE_STATUS_GOOD), "cannot set a settable option (status=%s)", sane_strstatus(status)); - + free(val_string); if (resolution_mode_opt) { - set_min_value(device, resolution_mode_optnum, - resolution_mode_opt); + set_min_value(device, resolution_mode_optnum, + resolution_mode_opt); test_scan(device); - set_max_value(device, resolution_mode_optnum, + set_max_value(device, resolution_mode_optnum, resolution_mode_opt); test_scan(device); - set_random_value(device, resolution_mode_optnum, + set_random_value(device, resolution_mode_optnum, resolution_mode_opt); test_scan(device); } else { @@ -1548,15 +1548,15 @@ static void test_scans(SANE_Device * device) } } else { if (resolution_mode_opt) { - set_min_value(device, resolution_mode_optnum, - resolution_mode_opt); + set_min_value(device, resolution_mode_optnum, + resolution_mode_opt); test_scan(device); - set_max_value(device, resolution_mode_optnum, + set_max_value(device, resolution_mode_optnum, resolution_mode_opt); test_scan(device); - set_random_value(device, resolution_mode_optnum, + set_random_value(device, resolution_mode_optnum, resolution_mode_opt); test_scan(device); } else { @@ -1593,7 +1593,7 @@ SANE_Status status; check(FATAL, (dev->vendor != NULL), "device vendor is NULL"); check(FATAL, (dev->type != NULL), "device type is NULL"); check(FATAL, (dev->model != NULL), "device model is NULL"); - + check(INF, ((strcmp(dev->type, "flatbed scanner") == 0) || (strcmp(dev->type, "frame grabber") == 0) || (strcmp(dev->type, "handheld scanner") == 0) || @@ -1784,7 +1784,7 @@ main (int argc, char **argv) status = sane_open ("opihndvses75bvt6fg", &device); check(WRN, (status == SANE_STATUS_INVAL), "sane_open() failed (%s)", sane_strstatus (status)); - + if (status == SANE_STATUS_GOOD) sane_close(device); @@ -1809,7 +1809,7 @@ main (int argc, char **argv) status = sane_init (&version_code, NULL); check(FATAL, (status == SANE_STATUS_GOOD), "sane_init failed with %s", sane_strstatus (status)); - + /* Check the device list */ rc = test_get_devices(&device_list, time); if (rc) goto the_exit; @@ -1833,7 +1833,7 @@ main (int argc, char **argv) if (!rc) goto the_exit; check(MSG, 0, "using device %s", devname); - + /* Test open close */ check(MSG, 0, "TEST: open/close"); for (i=0; i<10; i++) { @@ -1887,6 +1887,3 @@ main (int argc, char **argv) display_stats(); return(0); } - - - -- cgit v1.2.3