File test_remote_lpd.without_ping of Package yast2-printer

#! /bin/bash
#
# Send RFC1179 commands to the port 515 (lpd) on remote host $1 regarding queue $2
# and test whether queue $2 on remote host $1 would accept print jobs.
# Remote host $1 and queue $2 are required parameters.
# If no timeout $3 is given it is set to 10 seconds.
#
# Exits:   0 queue on host accepts print jobs (or at least connection possible to port 515 on host)
#          1 host $1 or queue $2 not set
#          2 no connection possible to port 515 on host
#          4 connection possible to port 515 on host but queue does not accept a print job
#            (queue may not exist or queueing disabled?)
#          5 connection possible to port 515 on host but no free source port to test queue on host
# The programs head, mkfifo, mktemp, sleep, tr, rm are in the coreutils RPM and therefore assumed to exist.
#
# Johannes Meixner <jsmeix@suse.de>, 2000, 2002, 2007, 2008, 2009, 2010, 2011, 2014
# Jan Holesovsky <kendy@suse.cz>, 2000
# Jiri Srain <jsrain@suse.cz>, 2002
# $Id: test_remote_lpd 43943 2008-01-28 13:38:58Z mzugec $

#set -x

# Make sure to have a clean environment:
export PATH="/sbin:/usr/sbin:/usr/bin:/bin"
export LC_ALL="POSIX"
export LANG="POSIX"
umask 022
# Disable bash file name globbing:
set -f

MY_NAME=${0##*/}
HOST="$1"
QUEUE="$2"
[ -z "$HOST" -o -z "$QUEUE" ] && { echo -en "\nUsage:\n$MY_NAME HOST QUEUE [TIMEOUT]\n" 1>&2 ; exit 1 ; }
TIMEOUT="$3"
[ -z "$TIMEOUT" ] && TIMEOUT=10

# Basic test whether connection is possible to port 515 on host:
# If the test fails, show an error message and exit with non-zero exit code.
# The outermost subshell avoids job control messages like "[1] job_pid" and "[1]+ Done..." or "[1]+ Terminated...".
# The hardcoded 2 seconds timeout is waited in any case so that the test needs always basically that timeout time.
# In POSIX shells wait returns the exit code of the job even if it had already terminated when wait was started,
# see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/wait.html that reads:
# "This volume of POSIX.1-2008 requires the implementation to keep the status
#  of terminated jobs available until the status is requested":
if ! ( ( echo -n '' >/dev/tcp/$HOST/515 ) & ECHO_PID=$! ; sleep 2s ; kill $ECHO_PID &>/dev/null ; wait $ECHO_PID )
then # The basic test failed:
     echo -en "\nNo connection possible to LPD port 515 on host '$HOST'."
     echo -en "\n(Network issue or wrong host or no LPD running or firewall active there?)\n\n"
     exit 2
fi

# The basic test succeeded:
echo -en "\nConnection possible to LPD port 515 on host '$HOST'\n"

# Use the binaries of the operating system (no aliases, functions, /usr/local/):
export NETCAT=$( type -ap netcat | head -n 1 )
export FUSER=$( type -ap fuser | head -n 1 )

# Test whether netcat and fuser are executable and
# if not, skip further testing and exit successfully as fallback:
if test -z "$NETCAT" -o -z "$FUSER"
then echo -en "\nCannot test if queue '$QUEUE' on host '$HOST' accepts print jobs because" 1>&2
     if test -z "$NETCAT"
     then echo -en "\n'netcat' not executable (no 'netcat' RPM installed?)" 1>&2
     fi
     if test -z "$FUSER"
     then echo -en "\n'fuser' not executable (no 'psmisc' RPM installed?)" 1>&2
     fi
     echo -en "\nSkipping this test and exiting successfully as fallback.\n" 1>&2
     exit 0
fi

# Create temporary fifos:
NETCAT_IN=$( mktemp -u /tmp/$MY_NAME.in.XXXXXX )
NETCAT_OUT=$( mktemp -u /tmp/$MY_NAME.out.XXXXXX )
mkfifo $NETCAT_IN
mkfifo $NETCAT_OUT

# Test the queue:
echo -en "\nTesting if queue '$QUEUE' on host '$HOST' accepts print jobs:\n"

# Find an available local port for connecting:
PORT=$( for P in 721 722 723 724 725 726 727 728 729 730 731
        do $FUSER -n tcp $P &>/dev/null || { echo $P ; break ; }
        done )
if test -z "$PORT"
then echo -en "\nFailed to test if queue '$QUEUE' on host '$HOST' accepts print jobs" 1>&2
     echo -en "\nbecause there is no LPD source port (721..731) available\n" 1>&2
     exit 5
fi

# Use source port $PORT and destination port 515 (LPD)
# "\002$QUEUE\n" is a request to receive a new job for $QUEUE
# The remote lpd sends '\000' if it accepts the request.
# Then we must send "\001\n" back which is a request to cancel the new job.
# After $TIMEOUT netcat would close the connection provided stdin of netcat
# was closed too which would happen if there is any response from the remote port.
# But as there may be no response from the remote port we have additionally
# a time bomb which would kill the netcat process after $TIMEOUT.

$NETCAT -w $TIMEOUT -p $PORT $HOST 515 <$NETCAT_IN >$NETCAT_OUT 2>/dev/null &
NETCAT_PID=$!
{ sleep ${TIMEOUT}s ; kill $NETCAT_PID &>/dev/null ; } &

RESULT=""
{ echo -en "\002$QUEUE\n" ; \
  RESULT=$( head --bytes=1 <$NETCAT_OUT | tr '\000' '0' ) ; \
  [ "$RESULT" = "0" ] && echo -en "\001\n" ; } >$NETCAT_IN

rm $NETCAT_IN
rm $NETCAT_OUT

[ "$RESULT" = "0" ] && { echo -en "\nQueue '$QUEUE' on host '$HOST' accepts print jobs\n" ; exit 0 ; }

echo -en "\nQueue '$QUEUE' on host '$HOST' does not accept print jobs (queue may not exist or queueing disabled?)\n"

# If $QUEUE does not accept jobs, print $QUEUE status in long format.
# "\004$QUEUE\n" is a request to receive $QUEUE status (very long output in case of LPRng).
echo -en "\nStatus of the queue '$QUEUE' (possibly empty or not available):\n\n"
echo -en "\004$QUEUE\n" | $NETCAT -w $TIMEOUT -p $PORT $HOST 515
exit 4

openSUSE Build Service is sponsored by