Commit 0fe94fc2 authored by Igor Pečovnik's avatar Igor Pečovnik
Browse files

patched source

parent f1b7b622
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
subdir = interface
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/scanbuttond/config.h
CONFIG_CLEAN_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(libdir)"
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libscanbtnd_interface_usb_la_LIBADD =
am_libscanbtnd_interface_usb_la_OBJECTS = libusbi.lo
libscanbtnd_interface_usb_la_OBJECTS = \
$(am_libscanbtnd_interface_usb_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include/scanbuttond
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libscanbtnd_interface_usb_la_SOURCES)
DIST_SOURCES = $(libscanbtnd_interface_usb_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
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@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
lib_LTLIBRARIES = libscanbtnd-interface_usb.la
libscanbtnd_interface_usb_la_SOURCES = libusbi.c ../include/scanbuttond/libusbi.h
libscanbtnd_interface_usb_la_LDFLAGS = -lusb -version-info 1:0:0
INCLUDES = $(all_includes) -I$(top_builddir)/include -I.
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu interface/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu interface/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: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
f=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@set -x; list='$(lib_LTLIBRARIES)'; for p in $$list; do \
p=$(am__strip_dir) \
echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \
$(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libscanbtnd-interface_usb.la: $(libscanbtnd_interface_usb_la_OBJECTS) $(libscanbtnd_interface_usb_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libscanbtnd_interface_usb_la_LDFLAGS) $(libscanbtnd_interface_usb_la_OBJECTS) $(libscanbtnd_interface_usb_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libusbi.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
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)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
for dir in "$(DESTDIR)$(libdir)"; 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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-libLTLIBRARIES
install-info: install-info-am
install-man:
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-info-am uninstall-libLTLIBRARIES
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am \
install-libLTLIBRARIES install-man 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 uninstall uninstall-am uninstall-info-am \
uninstall-libLTLIBRARIES
# 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:
// libusbi.h: libusb wrapper
// This file is part of scanbuttond.
// Copyleft )c( 2004-2006 by Bernhard Stiftner
//
// 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <usb.h>
#include <syslog.h>
#include "scanbuttond/libusbi.h"
#define TIMEOUT 10 * 1000 /* 10 seconds */
int invocation_count = 0;
libusb_handle_t* libusb_init(void)
{
libusb_handle_t* handle;
invocation_count++;
if (invocation_count == 1) {
syslog(LOG_INFO, "libusbi: initializing...");
usb_init();
}
handle = (libusb_handle_t*)malloc(sizeof(libusb_handle_t));
handle->devices = NULL;
libusb_rescan(handle);
return handle;
}
int libusb_search_interface(struct usb_device* device)
{
int found = 0;
int interface;
for (interface = 0; interface < device->config[0].bNumInterfaces && !found; interface++) {
switch (device->descriptor.bDeviceClass) {
case USB_CLASS_VENDOR_SPEC:
found = 1;
break;
case USB_CLASS_PER_INTERFACE:
switch (device->config[0].interface[interface].altsetting[0].bInterfaceClass) {
case USB_CLASS_VENDOR_SPEC:
case USB_CLASS_PER_INTERFACE:
case 16: /* data? */
found = 1;
break;
}
break;
}
}
interface--;
if (!found) return -1;
return interface;
}
int libusb_search_in_endpoint(struct usb_device* device)
{
int usb_in_ep = 0;
int usb_out_ep = 0;
struct usb_interface_descriptor *interface;
interface = &device->config[0].interface->altsetting[0];
int num;
for (num = 0; num < interface->bNumEndpoints; num++) {
struct usb_endpoint_descriptor *endpoint;
int address, direction, transfer_type;
endpoint = &interface->endpoint[num];
address = endpoint->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
if (transfer_type == USB_ENDPOINT_TYPE_BULK) {
if (direction) { /* in */
if (!usb_in_ep)
usb_in_ep = endpoint->bEndpointAddress;
} else { /* out */
if (!usb_out_ep)
usb_out_ep = endpoint->bEndpointAddress;
}
}
}
return usb_in_ep;
}
int libusb_search_out_endpoint(struct usb_device* device)
{
int usb_in_ep = 0;
int usb_out_ep = 0;
struct usb_interface_descriptor *interface;
interface = &device->config[0].interface->altsetting[0];
int num;
for (num = 0; num < interface->bNumEndpoints; num++) {
struct usb_endpoint_descriptor *endpoint;
int address, direction, transfer_type;
endpoint = &interface->endpoint[num];
address = endpoint->bEndpointAddress & USB_ENDPOINT_ADDRESS_MASK;
direction = endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK;
transfer_type = endpoint->bmAttributes & USB_ENDPOINT_TYPE_MASK;
if (transfer_type == USB_ENDPOINT_TYPE_BULK) {
if (direction) { /* in */
if (!usb_in_ep)
usb_in_ep = endpoint->bEndpointAddress;
} else { /* out */
if (!usb_out_ep)
usb_out_ep = endpoint->bEndpointAddress;
}
}
}
return usb_out_ep;
}
void libusb_attach_device(struct usb_device* device, libusb_handle_t* handle)
{
libusb_device_t* libusb_device = (libusb_device_t*)malloc(sizeof(libusb_device_t));
libusb_device->vendorID = device->descriptor.idVendor;
libusb_device->productID = device->descriptor.idProduct;
// the location string consists of bus number, followed by a colon (":"), and the device number
libusb_device->location = (char*)malloc(strlen(device->bus->dirname) + strlen(device->filename) + 2);
strcpy(libusb_device->location, device->bus->dirname);
strcat(libusb_device->location, ":");
strcat(libusb_device->location, device->filename);
libusb_device->device = device;
libusb_device->handle = NULL;
libusb_device->interface = libusb_search_interface(device);
if (libusb_device->interface < 0) {
free(libusb_device->location);
free(libusb_device);
return;
}
libusb_device->out_endpoint = libusb_search_out_endpoint(device);
if (libusb_device->out_endpoint < 0) {
free(libusb_device->location);
free(libusb_device);
return;
}
libusb_device->in_endpoint = libusb_search_in_endpoint(device);
if (libusb_device->in_endpoint < 0) {
free(libusb_device->location);
free(libusb_device);
return;
}
libusb_device->next = handle->devices;
handle->devices = libusb_device;
}
void libusb_detach_devices(libusb_handle_t* handle)
{
libusb_device_t* next;
while (handle->devices != NULL) {
next = handle->devices->next;
free(handle->devices->location);
free(handle->devices);
handle->devices = next;
}
}
void libusb_rescan(libusb_handle_t* handle)
{
struct usb_bus *bus;
struct usb_device *device;
libusb_detach_devices(handle);
usb_find_busses();
usb_find_devices();
handle->devices = NULL;
bus = usb_busses;
while (bus != NULL) {
device = bus->devices;
while (device != NULL) {
libusb_attach_device(device, handle);
device = device->next;
}
bus = bus->next;
}
}
int libusb_get_changed_device_count(void)
{
usb_find_busses();
return usb_find_devices();
}
libusb_device_t* libusb_get_devices(libusb_handle_t* handle)
{
return handle->devices;
}
int libusb_open(libusb_device_t* device)
{
int result;
if (!device || !device->device)
return -ENODEV;
device->handle = usb_open(device->device);
if (device->handle == NULL) {
syslog(LOG_ERR, "libusbi: could not open device %s", device->location);
return -ENODEV;
}
// Calling usb_set_configuration should not be necessary.
// It is even considered harmful, since it may disturb other processes
// which are currently communicating with the scanner!
//
// usb_set_configuration(device->handle,
// usb_device(device->handle)->config[0].bConfigurationValue);
result = usb_claim_interface(device->handle, device->interface);
switch (result) {
case 0:
return 0;
case -ENOMEM:
syslog(LOG_ERR, "libusbi: could not claim interface for device %s. (ENOMEM)",
device->location);
usb_close(device->handle);
return -ENODEV;
case -EBUSY:
syslog(LOG_ERR, "libusbi: could not claim interface for device %s. (EBUSY)",
device->location);
usb_close(device->handle);
return -EBUSY;
default:
syslog(LOG_ERR, "libusbi: could not claim interface for device %s. (code=%d)",
device->location, result);
usb_close(device->handle);
return -ENODEV;
}
}
int libusb_close(libusb_device_t* device)
{
int result;
result = usb_release_interface(device->handle, device->interface);
if (result < 0) {
syslog(LOG_ERR, "libusbi: could not release interface, error code=%d, device=%s",
result, device->location);
return result;
}
result = usb_close(device->handle);
if (result < 0) {
syslog(LOG_ERR, "libusbi: could not close usb device, error code=%d, device=%s",
result, device->location);
return result;
}
return 0;
}
int libusb_read(libusb_device_t* device, void* buffer, int bytecount)
{
int num_bytes = usb_bulk_read(device->handle, device->in_endpoint,
buffer, bytecount, TIMEOUT);
if (num_bytes<0) {
usb_clear_halt(device->handle, device->in_endpoint);
return 0;
}
return num_bytes;
}
int libusb_write(libusb_device_t* device, void* buffer, int bytecount)
{
int num_bytes = usb_bulk_write(device->handle, device->out_endpoint,
buffer, bytecount, TIMEOUT);
if (num_bytes<0) {
usb_clear_halt(device->handle, device->in_endpoint);
return 0;
}
return num_bytes;
}
void libusb_flush(libusb_device_t* device)
{
char buffer[16];
while (usb_bulk_read(device->handle, device->in_endpoint, buffer, 16, 500) > 0) {};
}
int libusb_control_msg(libusb_device_t* device, int requesttype, int request,
int value, int index, void* bytes, int size)
{
int num_bytes = usb_control_msg(device->handle, requesttype, request, value,
index, bytes, size, TIMEOUT);
if (num_bytes<0) {
// Doesn't seem to be needed... (bs, Jun 07 2005)
// usb_clear_halt(device->handle, device->in_endpoint);
return 0;
}
return num_bytes;
}
void libusb_exit(libusb_handle_t* handle)
{
invocation_count--;
if (invocation_count == 0)
syslog(LOG_INFO, "libusbi: shutting down...");
libusb_detach_devices(handle);
free(handle);
}
// loader.h: dynamic backend library loader
// This file is part of scanbuttond.
// Copyleft )c( 2005 by Bernhard Stiftner
//
// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <dlfcn.h>
#include <errno.h>
#include "scanbuttond/loader.h"
backend_t* load_backend(const char* filename)
{
char* error;
void* dll_handle = dlopen(filename, RTLD_NOW|RTLD_LOCAL);
if (!dll_handle) {
syslog(LOG_ERR, "loader: failed to load \"%s\". Error message: \"%s\"",
filename, dlerror());
return NULL;
}
dlerror(); // Clear any existing error
backend_t* backend = (backend_t*)malloc(sizeof(backend_t));
backend->handle = dll_handle;
backend->scanbtnd_get_backend_name = dlsym(dll_handle, "scanbtnd_get_backend_name");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_init = dlsym(dll_handle, "scanbtnd_init");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_rescan = dlsym(dll_handle, "scanbtnd_rescan");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_get_supported_devices = dlsym(dll_handle, "scanbtnd_get_supported_devices");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_open = dlsym(dll_handle, "scanbtnd_open");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_close = dlsym(dll_handle, "scanbtnd_close");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_get_button = dlsym(dll_handle, "scanbtnd_get_button");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_get_sane_device_descriptor = dlsym(dll_handle, "scanbtnd_get_sane_device_descriptor");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
backend->scanbtnd_exit = dlsym(dll_handle, "scanbtnd_exit");
if ((error = dlerror()) != NULL) {
syslog(LOG_ERR, "loader: dlsym failed! Error message \"%s\"", error);
dlclose(dll_handle);
free(backend);
return NULL;
}
return backend;
}
void unload_backend(backend_t* backend)
{
dlclose(backend->handle);
free(backend);
}
This source diff could not be displayed because it is too large. You can view the blob instead.
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:
// scanbuttond.c: the actual daemon ("frontend")
// This file is part of scanbuttond.
// Copyleft )c( 2004-2006 by Bernhard Stiftner
//
// 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 <sys/stat.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <syslog.h>
#include <errno.h>
#include <getopt.h>
#include "scanbuttond/config.h"
#include "scanbuttond/common.h"
#include "scanbuttond/scanbuttond.h"
#include "scanbuttond/loader.h"
#define DEF_BACKEND_FILENAME STRINGIFY(LIB_DIR) "/libscanbtnd-backend_meta.so"
#define DEF_BUTTONPRESSED_SCRIPT STRINGIFY(CFG_DIR) "/buttonpressed.sh"
#define DEF_INITSCANNER_SCRIPT STRINGIFY(CFG_DIR) "/initscanner.sh"
#define DEF_POLL_DELAY 333000L
#define MIN_POLL_DELAY 1000L
#define DEF_RETRY_DELAY 2000000L
#define MIN_RETRY_DELAY 10000L
#define BUF_SIZE 256
static char* connection_names[NUM_CONNECTIONS] =
{ "none", "libusb" };
static struct option const long_opts[] = {
{"foreground", no_argument, NULL, 'f'},
{"backend", required_argument, NULL, 'b'},
{"buttonscript", required_argument, NULL, 's'},
{"initscript", required_argument, NULL, 'S'},
{"pollingdelay", required_argument, NULL, 'p'},
{"retrydelay", required_argument, NULL, 'r'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
};
char* buttonpressed_script;
char* initscanner_script;
char* backend_filename;
backend_t* backend;
long poll_delay;
long retry_delay;
int daemonize;
int killed = 0;
char* path;
char* scanbtnd_get_connection_name(int connection)
{
return connection_names[connection];
}
void shutdown(void)
{
syslog(LOG_INFO, "shutting down...");
backend->scanbtnd_exit();
unload_backend(backend);
syslog(LOG_DEBUG, "shutdown complete");
closelog();
}
// Ensures a graceful exit on SIGHUP/SIGTERM/SIGINT/SIGSEGV
void sighandler(int i)
{
killed = 1;
syslog(LOG_INFO, "received signal %d", i);
shutdown();
exit(i == SIGTERM ? EXIT_SUCCESS : EXIT_FAILURE);
}
// Executes an external program and wait until it terminates
void execute_and_wait(const char* program)
{
system(program);
}
void list_devices(scanner_t* devices)
{
scanner_t* dev = devices;
while (dev != NULL) {
syslog(LOG_INFO, "found scanner: vendor=\"%s\", product=\"%s\", connection=\"%s\", sane_name=\"%s\"",
dev->vendor, dev->product, scanbtnd_get_connection_name(dev->connection),
backend->scanbtnd_get_sane_device_descriptor(dev));
dev = dev->next;
}
}
void show_version(void)
{
printf("This is scanbuttond, version %s\n", VERSION);
printf("Copyleft )c( 2004-2006 by Bernhard Stiftner and contributors.\n");
printf("Scanbuttond comes with ABSOLUTELY NO WARRANTY!\n");
printf("This is free software, and you are welcome to redistribute it\n");
printf("under certain conditions; see the file COPYING for details.\n");
}
void show_usage(void)
{
printf("Usage: scanbuttond [OPTION]...\n\n");
printf("Starts a script when a button on a scanner has been pressed.\n\n");
printf("Options:\n");
printf(" -f, --foreground Run in foreground instead of background\n");
printf(" -b, --backend=FILE Use the specified backend library file\n");
printf(" default: %s\n", DEF_BACKEND_FILENAME);
printf(" -s, --buttonscript=SCRIPT The name of the script to be run when a button has been pressed\n");
printf(" default: %s\n", DEF_BUTTONPRESSED_SCRIPT);
printf(" -S, --initscript=SCRIPT The name of the script to be run to initialize the scanners\n");
printf(" default: %s\n", DEF_INITSCANNER_SCRIPT);
printf(" -p, --pollingdelay=DELAY The polling delay (ms), default: %ld\n", DEF_POLL_DELAY);
printf(" -r, --retrydelay=DELAY The retry delay (ms), default: %ld\n", DEF_RETRY_DELAY);
printf(" -h, --help Shows this screen\n");
printf(" -v, --version Shows the version\n");
}
void process_options(int argc, char** argv)
{
int c;
buttonpressed_script = NULL;
initscanner_script = NULL;
poll_delay = -1;
retry_delay = -1;
daemonize = 1;
while ((c = getopt_long (argc, argv, "fb:s:S:p:r:hv", long_opts, NULL)) != -1) {
switch (c) {
case 'f':
daemonize = 0;
break;
case 'b':
backend_filename = optarg;
break;
case 's':
buttonpressed_script = optarg;
break;
case 'S':
initscanner_script = optarg;
break;
case 'p':
poll_delay = atol(optarg);
if (poll_delay < MIN_POLL_DELAY) {
printf("Invalid polling delay (%ld). Must be at least %ld.\n",
poll_delay, MIN_POLL_DELAY);
exit(EXIT_FAILURE);
}
break;
case 'r':
retry_delay = atol(optarg);
if (retry_delay < MIN_RETRY_DELAY) {
printf("Invalid retry delay (%ld). Must be at least %ld.\n",
retry_delay, MIN_RETRY_DELAY);
exit(EXIT_FAILURE);
}
break;
case 'h':
show_usage();
exit(EXIT_SUCCESS);
break;
case 'v':
show_version();
exit(EXIT_SUCCESS);
break;
}
}
if (backend_filename == NULL)
backend_filename = DEF_BACKEND_FILENAME;
if (buttonpressed_script == NULL)
buttonpressed_script = DEF_BUTTONPRESSED_SCRIPT;
if (initscanner_script == NULL)
initscanner_script = DEF_INITSCANNER_SCRIPT;
if (poll_delay == -1)
poll_delay = DEF_POLL_DELAY;
if (retry_delay == -1)
retry_delay = DEF_RETRY_DELAY;
}
int main(int argc, char** argv)
{
int button;
int result;
pid_t pid, sid;
scanner_t* scanners;
scanner_t* scanner;
process_options(argc, argv);
backend = load_backend(backend_filename);
if (!backend) {
printf("Unable to load backend library \"%s\"!\n", backend_filename);
exit(EXIT_FAILURE);
}
// daemonize
if (daemonize) {
pid = fork();
if (pid < 0) {
printf("Can't fork!\n");
exit(EXIT_FAILURE);
} else if (pid > 0) {
exit(EXIT_SUCCESS);
}
}
umask(0);
openlog(NULL, 0, LOG_DAEMON);
// create a new session for the child process
if (daemonize) {
sid = setsid();
if (sid < 0) {
syslog(LOG_ERR, "Could not create a new SID! Terminating.");
exit(EXIT_FAILURE);
}
}
// Change the current working directory
if ((chdir("/")) < 0) {
syslog(LOG_WARNING, "Could not chdir to /. Hmmm, strange... "\
"Trying to continue.");
}
// close standard file descriptors
if (daemonize) {
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
// setup the environment
char* oldpath = getenv("PATH");
char* dir = dirname(argv[0]);
path = (char*)malloc(strlen(oldpath) + strlen(dir) + 1);
strcpy(path, oldpath);
strcat(path, ":");
strcat(path, dir);
setenv("PATH", path, 1);
free(path);
syslog(LOG_DEBUG, "running scanner initialization script...");
execute_and_wait(initscanner_script);
syslog(LOG_DEBUG, "initialization script executed.");
if (backend->scanbtnd_init() != 0) {
syslog(LOG_ERR, "Error initializing backend. Terminating.");
exit(EXIT_FAILURE);
}
scanners = backend->scanbtnd_get_supported_devices();
if (scanners == NULL) {
syslog(LOG_WARNING, "no known scanner found yet, " \
"waiting for device to be attached");
}
list_devices(scanners);
signal(SIGTERM, &sighandler);
signal(SIGHUP, &sighandler);
signal(SIGINT, &sighandler);
signal(SIGSEGV, &sighandler);
signal(SIGCLD, SIG_IGN);
syslog(LOG_INFO, "scanbuttond started");
// main loop
while (killed == 0) {
if (scanners == NULL) {
syslog(LOG_DEBUG, "rescanning devices...");
backend->scanbtnd_rescan();
scanners = backend->scanbtnd_get_supported_devices();
if (scanners == NULL) {
syslog(LOG_DEBUG, "no supported devices found. rescanning in a few seconds...");
usleep(retry_delay);
continue;
}
syslog(LOG_DEBUG, "found supported devices. running scanner initialization script...");
execute_and_wait(initscanner_script);
syslog(LOG_DEBUG, "initialization script executed.");
scanners = backend->scanbtnd_get_supported_devices();
continue;
}
scanner = scanners;
while (scanner != NULL) {
result = backend->scanbtnd_open(scanner);
if (result != 0) {
syslog(LOG_WARNING, "scanbtnd_open failed, error code: %d", result);
if (result == -ENODEV) {
// device has been disconnected, force re-scan
syslog(LOG_INFO, "scanbtnd_open returned -ENODEV, device rescan will be performed");
scanners = NULL;
usleep(retry_delay);
break;
}
usleep(retry_delay);
break;
}
button = backend->scanbtnd_get_button(scanner);
backend->scanbtnd_close(scanner);
if ((button > 0) && (button != scanner->lastbutton)) {
syslog(LOG_INFO, "button %d has been pressed.", button);
scanner->lastbutton = button;
char cmd[BUF_SIZE];
snprintf(cmd, BUF_SIZE, "%s %d %s", buttonpressed_script, button,
backend->scanbtnd_get_sane_device_descriptor(scanner));
execute_and_wait(cmd);
}
if ((button == 0) && (scanner->lastbutton > 0)) {
syslog(LOG_INFO, "button %d has been released.", scanner->lastbutton);
scanner->lastbutton = button;
}
scanner = scanner->next;
}
usleep(poll_delay);
}
syslog(LOG_WARNING, "exited main loop!?!");
shutdown();
exit(EXIT_SUCCESS);
}
pkgsysconfdir = $(sysconfdir)/$(PACKAGE)
pkgsysconf_SCRIPTS = buttonpressed.sh initscanner.sh
EXTRA_DIST = $(pkgsysconf_SCRIPTS)
# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004, 2005 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@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
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@
subdir = scripts
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/include/scanbuttond/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(pkgsysconfdir)"
pkgsysconfSCRIPT_INSTALL = $(INSTALL_SCRIPT)
SCRIPTS = $(pkgsysconf_SCRIPTS)
SOURCES =
DIST_SOURCES =
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
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@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
pkgsysconfdir = $(sysconfdir)/$(PACKAGE)
pkgsysconf_SCRIPTS = buttonpressed.sh initscanner.sh
EXTRA_DIST = $(pkgsysconf_SCRIPTS)
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu scripts/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: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-pkgsysconfSCRIPTS: $(pkgsysconf_SCRIPTS)
@$(NORMAL_INSTALL)
test -z "$(pkgsysconfdir)" || $(mkdir_p) "$(DESTDIR)$(pkgsysconfdir)"
@list='$(pkgsysconf_SCRIPTS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
if test -f $$d$$p; then \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
echo " $(pkgsysconfSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgsysconfdir)/$$f'"; \
$(pkgsysconfSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgsysconfdir)/$$f"; \
else :; fi; \
done
uninstall-pkgsysconfSCRIPTS:
@$(NORMAL_UNINSTALL)
@list='$(pkgsysconf_SCRIPTS)'; for p in $$list; do \
f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
echo " rm -f '$(DESTDIR)$(pkgsysconfdir)/$$f'"; \
rm -f "$(DESTDIR)$(pkgsysconfdir)/$$f"; \
done
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$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 $(SCRIPTS)
installdirs:
for dir in "$(DESTDIR)$(pkgsysconfdir)"; 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:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am: install-pkgsysconfSCRIPTS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-pkgsysconfSCRIPTS
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
distclean distclean-generic distclean-libtool distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man \
install-pkgsysconfSCRIPTS install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \
uninstall-info-am uninstall-pkgsysconfSCRIPTS
# 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:
#!/bin/sh
# This script is started by scanbuttond whenever a scanner button has been pressed.
# Scanbuttond passes the following parameters to us:
# $1 ... the button number
# $2 ... the scanner's SANE device name, which comes in handy if there are two or
# more scanners. In this case we can pass the device name to SANE programs
# like scanimage.
TMPFILE="/tmp/scan.tiff"
LOCKFILE="/tmp/copy.lock"
case $1 in
1)
echo "button 1 has been pressed on $2"
# This example turns your scanner+printer into a photocopier.
# Fine-tuned for the Epson Perfection 2400, the HP LaserJet 1200 and
# ISO A4 paper size so that the scanned document matches the printer
# output as closely as possible.
#
# if [ -f $LOCKFILE ]; then
# echo "Error: Another scanning operation is currently in progress"
# exit
# fi
# touch $LOCKFILE
# rm -f $TMPFILE
# scanimage --device-name $2 --format tiff --mode Gray --quick-format A4 \
# --resolution 300 --sharpness 0 --brightness -3 \
# --gamma-correction "High contrast printing" > $TMPFILE
# tiff2ps -z -w 8.27 -h 11.69 $TMPFILE | lpr
# rm -f $LOCKFILE
#
;;
2)
echo "button 2 has been pressed on $2"
;;
3)
echo "button 3 has been pressed on $2"
;;
4)
echo "button 4 has been pressed on $2"
;;
esac
#!/bin/sh
# This script is executed whenever scanbuttond
# finds new devices.
# If your scanner needs a firmware upload or any other kind
# of special action to be taken on initialization, put
# the apropriate command here.
# Example:
# scanimage -n
# or
# sane-find-scanners
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment