tech-pkg archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Samba 3.x: findsmb as Bourne shell (getting rid of Perl)
As I have suggested, in order to get rid of Perl as a run dependency
to Sambe (at least 3.x) here is a rewrite of the Perl findsmb script.
It corrects several bugs:
- the broadcast address option could not be used (shifting too
much);
- name was set to "unknown nis name" and then, if name was set
(even with this "false" value) a query was sent;
- there was no help option;
- debug information was sent to stdout;
- the output was not correctly aligned to the header.
I'd like others with Samba to test the script before submitting it.
There is one variable to adjust eventually: SAMBABINDIR (it exists in
the Perl script). Default value is "/usr/pkg/bin"
I have added one supplementary variable: HOSTS_FILE that defaults to
"/etc/hosts" for making the equivalent to perl:gethostbyaddr (this
file is not used if getent(1) exists in the PATH).
You can set both SAMBABINDIR and HOSTS_FILE in the environment if the
default are not correct (correct values would be set at compile time).
--
Thierry Laronde <tlaronde +AT+ polynum +dot+ com>
http://www.kergis.com/
http://www.sbfa.fr/
Key fingerprint = 0FF7 E906 FBAF FE95 FD89 250D 52B1 AE95 6006 F40C
#!/bin/sh
# Rewrite of the SAMBA Perl script findsmb to a POSIX.2 Bourne shell
# compliant one. (Thierry Laronde, 2019-07-21)
set -e
usage="Usage: findsmb [-h] [-d|-D] [-r] [subnet_broadcast_address]
List machines on the current subnet or the subnet specified.
Options:
-d|-D enable Debug
-h display this Help message
-r -r option passed to nmblookup when finding netbios name
Output:
Local master browsers are prefixed by a '+'.
Domain master browsers are prefixed by a '*'.
"
#========== Installation dependent
#
: ${TMPDIR:=/tmp}
: ${SAMBABINDIR:="/usr/pkg/bin"}
: ${HOSTS_FILE:="/etc/hosts"}
#========== NOTHING TO CHANGE BELOW
#========== Subr
#
iplist="$TMPDIR/$$.iplist"
nmblookuplist="$TMPDIR/$$.nmblookuplist"
smbclientlist="$TMPDIR/$$.smbclientlist"
clean_tmp()
{
rm -f "$iplist" "$nmblookuplist" "$smbclientlist"
}
error()
{
printf "$@" >&2
clean_tmp
exit 1
}
# Does gethostbyaddr. Start by looking local host names in the hosts
# file and query DNS if this fails.
#
# Takes: an ip address;
# Returns: a string, perhaps empty, with the name.
#
getname()
{
junk=
# Looking local defined names.
#
if type getent >/dev/null 2>&1; then
junk=$(getent hosts $1\
| sed 's/[ ][ ]*/ /g'\
| cut -d ' ' -f 2)
else
junk=$(sed -n /^$1[ ]/'s/[ ][ ]*/ /gp' "$HOSTS_FILE"\
| cut -d ' ' -f 2)
fi
if test ! -z "$junk"; then # DONE
echo $junk
return
fi
# Not found; querying DNS.
#
if type nslookup >/dev/null 2>&1; then
junk=$(nslookup $1 | sed -n 's/^.*name =[ ]*\([^ ][^ ]*\)$/\1/p')
elif type dig >/dev/null 2>&1; then
junk=$(dig -x $1 | sed -e '/^;/d' -e '/^$/d'\
-e 's/^.*[ ]\([^ ][^ ]*\)/\1/'\
| sed 1q)
fi
echo $junk
}
#========== Checking: no stores
#
debug=NO
nmblookup_opt=
broadcast_opt=
while test $# -gt 0; do
case "$1" in
-h) echo "$usage"; exit 0;;
-d|-D) debug=YES;;
-r) nmbloolup_opt="-r";;
-*) printf "$0: unknown option '$1'\n"
error "$usage";;
*) broadcast_opt="-B $1";;
esac
shift
done
#========== Stores
# We start by getting the addresses that will be the first field of
# information published.
#
{ $SAMBABINDIR/nmblookup $broadcast_opt '*' --debuglevel=0\
|| error "Can't run nmblookup '*'.\n"; } >"$iplist"
# Printing header
#
printf "\n *=DMB\n"
printf " +=LMB\n"
printf "IP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $broadcast_opt\n"
# Note: the "%c" circumvent a bug treating a leading - as option.
#
printf "%c--------------------------------------------------------------------\n" -
# For each address, we will try to fill the remaining informations.
# So a record is 3 fields: ip, name and info.
#
sed -n -e 's/ \*<00>.*$//p' -e 's/[ ]*//g' "$iplist" | sort -n\
| while read ip; do
# Trying to define the second field: the name.
#
# Start by querying via netbios.
#
{ $SAMBABINDIR/nmblookup $nmbloolup_opt -A $ip --debuglevel=0\
|| error "Can't get nmb name list.\n"; } >"$nmblookuplist"
record=$(sed -n '/<00>/{p; q;}' "$nmblookuplist")
if test ! -z "$record"; then # got a record from netbios
is_groupname=$(echo $record | sed -n '/GROUP/p')
if test ! -z "$is_groupname"; then
name=$(getname $ip)
else
name=$(echo $record\
| sed 's/^[ ]*\([^ ].*[^ ]\)[ ][ ]*<00>.*$/\1/')
fi
# do an smbclient command on the netbios name if set.
#
if ! test -z "$name"; then
{ $SAMBABINDIR/smbclient -L $name -I $ip -N --debuglevel=1 2>&1\
|| error "Can't do smbclient command.\n"; } >"$smbclientlist"
if test $debug = YES; then
printf "\n======================== DEBUG: BEGIN ========================\n" >&2
printf "=================== DEBUG: nmblookup output ===================\n" >&2
cat "$nmblookuplist" >&2
printf "=================== DEBUG: smbclient output ===================\n" >&2
cat "$smbclientlist" >&2
printf "========================= DEBUG: END =========================\n\n" >&2
fi
# We will try to set the third field: informations.
#
info=$(sed -n '/OS=/{p; q;}' "$smbclientlist")
if test ! -z "$info"; then
# Strip out descriptions to make line shorter.
#
info=$(echo $info | sed -e 's/Domain=//'\
-e 's/OS=//' -e 's/Server=//')
else # no OS= string in response (WIN95 client)
# for WIN95 clients get workgroup name from nmblookup response
#
record=$(sed -n '/<00> - <GROUP>/{p; q;}' "$nmblookuplist")
if test ! -z "$record"; then
info=$(echo $record\
| sed 's/^[ ]*\([^ ].*[^ ]\)[ ][ ]*<00>.*$/\1/')
info="[$info]"
else
info="Unknown Workgroup"
fi
fi
else
name="unknown nis name";
fi
# see if machine registered a local master browser name
if grep -q '<1d>' "$nmblookuplist"; then
master='+' # indicate local master browser
if grep -q '<1b>' "$nmblookuplist"; then # how about domain master browser?
master='*' # indicate domain master browser
fi
else
master=' ' # not a browse master
fi
info="$master$info"
else # didn't get a record by netbios
name=$(getname $ip)
test ! -z "$name" || name="unknown nis name";
info=""
if test $debug = YES; then
printf "\n======================== DEBUG: BEGIN ========================\n" >&2
printf "=================== DEBUG: nmblookup output ===================\n" >&2
cat "$nmblookuplist" >&2
printf "========================= DEBUG: END =========================\n\n" >&2
fi
fi
# Publish the 3 fields.
#
printf "%-16s%-16s%s\n" "$ip" "$name" "$info"
done
clean_tmp
exit 0
Home |
Main Index |
Thread Index |
Old Index