#! /bin/bash

# Johannes Meixner <jsmeix@suse.de>, 2004, 2005, 2006, 2007, 2008, 2010
#
# Copyright (c) 2010 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# 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, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com

#set -x

export PATH="/sbin:/usr/sbin:/usr/bin:/bin"
export LC_ALL="POSIX"
export LANG="POSIX"
umask 022

MY_NAME=${0##*/}
SANE_DEVICE="$1"
[ -z "$SANE_DEVICE" ] && { echo -en "\nUsage:\n$MY_NAME SANE_device\n" 1>&2 ; exit 1 ; }

# The test via "scanimage -d $SANE_DEVICE -T" does not work for any backend
# because it tries using a variety of buffer sizes during the data transfer,
# followed by a cancel instead of completing the scan.
# This might put some scanners/backends into an inconsistent state,
# when they do not properly implement the cancel, see the Novell/Suse Bugzilla bug
# https://bugzilla.novell.com/show_bug.cgi?id=344534
# Therefore the test is done via "scanimage -d $SANE_DEVICE -v >/dev/null"
# which does a complete scan and "-v" provides some basic info what it does.
# The exit code of "scanimage" is needed as exit code of this script.
# Therefore this command must run in the foreground.
# Therefore a simple time bomb background process is started before it.
# This time bomb background process is normally killed at the end.
# As a signal is processed not until a "sleep" has finished,
# it is crucial not to do simply "sleep $MAXIMUM_WAIT"
# but to do "for i in $( seq $MAXIMUM_WAIT ) ; do sleep 1 ; done"
# otherwise it would wait in any case until "sleep $MAXIMUM_WAIT" has finished.
MAXIMUM_WAIT="120"
if [ -x /usr/bin/scanimage ]
then ( for i in $( seq $MAXIMUM_WAIT ) ; do sleep 1 ; done ; killall -9 scanimage &>/dev/null ) &
     timebombPID=$!
     scanimage -d $SANE_DEVICE -v >/dev/null
     scanimageEXIT=$?
     # If the timebomb is still running, scanimage has finished
     # and killing the timebomb will be successful.
     if kill -9 $timebombPID &>/dev/null
     then exit $scanimageEXIT
     else echo -e "\nAborted scanimage after $MAXIMUM_WAIT seconds timeout." 1>&2
          exit 3
     fi
else 
    echo "Cannot execute /usr/bin/scanimage" 1>&2
    exit 2
fi

exit 0

