Permalink
Browse files

Version 3.3.0 (2012-02-03)

 * allow checkhosts(1) to read hosts from stdin or on the command-line
 * allow checkhosts(1) to print noping,nossh,nosshd info to stderr instead
   of into separate files
  • Loading branch information...
1 parent 158a179 commit 5aeb55ed1ae3c8a994c8426ebae1fb1ae3087d7a @jschauma committed Feb 3, 2012
Showing with 103 additions and 33 deletions.
  1. +5 −0 CHANGES
  2. +31 −5 doc/checkhosts.1
  3. +67 −28 src/checkhosts
View
@@ -1,3 +1,8 @@
+Version 3.3.0 (2012-02-03)
+ * allow checkhosts(1) to read hosts from stdin or on the command-line
+ * allow checkhosts(1) to print noping,nossh,nosshd info to stderr instead
+ of into separate files
+
Version 3.2.1 (2011-06-11)
* fix tyop noted by blysik@ in
https://github.com/jschauma/scanmaster/pull/2
View
@@ -1,18 +1,19 @@
.\" This manual page was originally written by Jan Schaumann
.\" <jschauma@yahoo-inc.com> in February 2007.
-.Dd January 28, 2011
+.Dd February 03, 2012
.Dt CHECKHOSTS 1
.Os
.Sh NAME
.Nm checkhosts
.Nd scan a list of hosts and run a given script on them
.Sh SYNOPSIS
.Nm
-.Op Fl HIPSbh
+.Op Fl HIPSbeh
.Op Fl A Ar authmode
.Op Fl o Ar dir
.Op Fl r Ar script
-.Fl f Ar file
+.Op Fl f Ar file
+.Op Ar hostname Oo Ar ... Oc
.Sh DESCRIPTION
For every host in the input, the
.Nm
@@ -70,6 +71,12 @@ This slightly changes the default behaviour and should normally only be
set by the invoking
.Xr scanhosts 1
script.
+.It Fl e
+Print errors relating to host reachability to stderr.
+That is, instead of sorting hosts that don't ping, don't listen on port 22
+or cannot be reached into different output files, simply report them on
+stderr.
+(Hosts that were successfully processed will then not be reported at all.)
.It Fl f Ar file
Read the list of hosts from
.Ar file .
@@ -116,15 +123,34 @@ output in any files readable by anybody else.
.Sh INPUT
Input can be provided via the
.Fl f Ar file
-flag.
+flag, as arguments the command-line or from stdin.
Multiple
.Fl f Ar filename
are allowed.
+.Pp
+Hostnames or IP addresses provided as arguments on the command-line are
+processed first.
+Next,
+.Nm
+will process all input files.
+If (and only if!) no input files are provided and no arguments were given
+on the command-line,
+.Nm
+will read lines to process from stdin.
+.Pp
The input format of the file is two fields per line, the first field being
the hostname, the second the IP address of the host.
Lines starting with a # are treated as comments and ignored.
+.Pp
+If no files are given, then
+.Nm
+will read input lines from stdin.
+.Pp
+
.Sh OUTPUT
-Output is generated into the following distinct files:
+Unless the
+.Fl e
+flag is given, output will be generated into the following distinct files:
.Bl -tag -width hosts_checked
.It hosts_checked
The list of hosts that
View
@@ -51,6 +51,7 @@ TDIR="${TMPDIR:-/tmp}"
AUTHMODE="pubkey"
BACKGROUND='no'
HEADLESS='yes'
+INPUT_ARGS=
INPUT_FILES=
OUTPUT_DIR=${TDIR}
SCRIPT="remote.sh"
@@ -60,6 +61,7 @@ SCP_WRAPPER=".checkhosts-scp"
CHECK_PING='yes'
CHECK_SSHD='yes'
HOSTNAMES_ONLY='no'
+WANT_ERRORS=
###
### Subroutines
@@ -71,7 +73,7 @@ HOSTNAMES_ONLY='no'
# inputs : none
# outputs : help message
-usage () {
+usage() {
cat <<EOF
Usage: ${0##*/} [-HIPSbh] [-A authmode] [-o dir] [-r script] -f file
-A Specify ssh authentication mode.
@@ -98,7 +100,7 @@ EOF
# assumed to be an IP address
# outputs : appends to the three output files
-checkhost () {
+checkhost() {
local input="${1}"
local host="${1%% *}"
local ip="${1##* }"
@@ -143,7 +145,9 @@ checkhost () {
sshopts="${sshopts} -o NumberOfPasswordPrompts=1"
fi
- echo "${input}" >> ${OUTFILE_CHECKED}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo "${input}" >> ${OUTFILE_CHECKED}
+ fi
if [ "${HOSTNAMES_ONLY}" = "yes" -o "${host}" = "${ip}" ]; then
target="${host}"
@@ -152,15 +156,23 @@ checkhost () {
if [ "${CHECK_PING}" = "yes" ]; then
ping -c 1 -i 1 -t 3 -q ${target} >/dev/null 2>&1 || {
- echo ${input} >> ${OUTFILE_NOPING}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo ${input} >> ${OUTFILE_NOPING}
+ else
+ echo "Ping error: ${input}" >&2
+ fi
return 1
# NOTREACHED
}
fi
if [ "${CHECK_SSHD}" = "yes" ]; then
check_sshd ${target} || {
- echo ${input} >> ${OUTFILE_NOSSHD}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo ${input} >> ${OUTFILE_NOSSHD}
+ else
+ echo "sshd error: ${input}" >&2
+ fi
return 1
# NOTREACHED
}
@@ -170,55 +182,83 @@ checkhost () {
${SCP_WRAPPER} ${sshopts} ${SSHOPTS} ${SCRIPT} ${target}:${remotefile}
if [ $? -gt 0 ]; then
- echo ${input} >> ${OUTFILE_NOSSH}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo ${input} >> ${OUTFILE_NOSSH}
+ else
+ echo "ssh error: ${input}" >&2
+ fi
return 1
# NOTREACHED
fi
- host_output=$(${SSH_WRAPPER} ${sshopts} ${SSHOPTS} ${target} "${rcmd}")
+ host_output=$(${SSH_WRAPPER} ${sshopts} ${SSHOPTS} ${target} "${rcmd} 2>/dev/null")
else
- host_output=$(${SSH_WRAPPER} ${sshopts} ${SSHOPTS} ${target} "${remote_shell}" < ${SCRIPT})
+ host_output=$(${SSH_WRAPPER} ${sshopts} ${SSHOPTS} ${target} "${remote_shell}" < ${SCRIPT} 2>/dev/null)
fi
rval=$?
if [ ${rval} -eq 255 ]; then
- echo ${input} >> ${OUTFILE_NOSSH}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo ${input} >> ${OUTFILE_NOSSH}
+ else
+ echo "ssh error: ${input}" >&2
+ fi
return 1
# NOTREACHED
elif [ ${rval} -gt 0 ]; then
outfile="${OUTFILE_EXITCODE}_${rval}"
fi
- echo "${host},${ip},${host_output}" | tr '' '\n' >> ${outfile}
+ if [ -z "${WANT_ERRORS}" ]; then
+ echo "${host},${ip},${host_output}" | tr '' '\n' >> ${outfile}
+ fi
}
-# function : process_input_files
-# purpose : work of the lines in all input files
+# function : process_input
+# purpose : work of the lines in all input files, arguments or stdin
# usage : process_input_files
# inputs : none, operates on global INPUT_FILES
# outputs : none
-process_input_files () {
+process_input() {
+ local file line
- local file
+ # items given as arguments first...
+ for line in ${INPUT_ARGS}; do
+ checkhost "$line"
+ done
+ # next, any input files
for file in ${INPUT_FILES}; do
- if [ -r "${file}" ]; then
- local readonly tmpf=$(mktemp ${TDIR}/checkhosts.$$.XXXXXX)
- grep -v "^#" ${file} > ${tmpf}
- oIFS=${IFS}
- IFS='
+ oIFS=${IFS}
+ # careful: there's a newline in quotes
+ IFS='
'
- for line in $(cat ${tmpf}); do
+ if [ -r "${file}" ]; then
+ for line in $(grep -v "^#" ${file}); do
IFS=${oIFS}
checkhost "${line}"
done
- rm ${tmpf}
else
echo "Cannot read ${file}." >&2
fi
done
+
+ # if we haven't done anything, then we try to read input from
+ # stdin
+ if [ -z "${INPUT_FILES}" -a -z "${INPUT_ARGS}" ]; then
+ oIFS=${IFS}
+ # careful: there's a newline in quotes
+ IFS='
+'
+ while read line; do
+ IFS=${oIFS}
+ checkhost "${line}"
+ done
+ fi
+
+
}
# function : check_sshd
@@ -282,7 +322,7 @@ wrap_ssh() {
###
main() {
- while getopts 'A:HIPSbf:ho:r:' opt; do
+ while getopts 'A:HIPSbef:ho:r:' opt; do
case ${opt} in
A)
AUTHMODE="${OPTARG}"
@@ -302,6 +342,9 @@ main() {
b)
BACKGROUND='yes'
;;
+ e)
+ WANT_ERRORS='yes'
+ ;;
f)
INPUT_FILES="${INPUT_FILES} ${OPTARG}"
;;
@@ -330,11 +373,7 @@ main() {
done
shift $(($OPTIND - 1))
- if [ -z "${INPUT_FILES}" -a $# -lt 1 ]; then
- usage
- exit 1
- # NOTREACHED
- fi
+ INPUT_ARGS="$@"
if [ ! -r ${SCRIPT} ]; then
echo "Unable to read script \"${SCRIPT}\"." >&2
@@ -351,7 +390,7 @@ main() {
wrap_ssh
- process_input_files
+ process_input
return 0
}

0 comments on commit 5aeb55e

Please sign in to comment.