49 lines
1.7 KiB
Bash
49 lines
1.7 KiB
Bash
#!/bin/bash
|
|
#
|
|
# Purpose : Find what's on the local network over mDNS (Avahi), for the
|
|
# configure.d items that set up servers, printers and storage on it.
|
|
# Source this file.
|
|
|
|
# Every service Avahi can see, or only those of type $1 (e.g. _ipp._tcp), one
|
|
# per line after waiting a few seconds for answers:
|
|
# "name|type|host|address|port|txt". IPv4 only, so a machine isn't listed once
|
|
# per address family. The name has Avahi's escapes decoded.
|
|
mdns_services() {
|
|
local name type host address port txt
|
|
timeout 15 avahi-browse "${1:---all}" --resolve --terminate --parsable --no-db-lookup 2> /dev/null \
|
|
| awk -F';' '$1 == "=" && $3 == "IPv4"' \
|
|
| while IFS=';' read -r _ _ _ name type _ host address port txt; do
|
|
printf '%s|%s|%s|%s|%s|%s\n' "$(mdns_unescape "$name")" "$type" "$host" "$address" "$port" "$txt"
|
|
done | sort -u
|
|
}
|
|
|
|
# Avahi writes a space as \032 and a dot in a name as \. (decimal escapes)
|
|
mdns_unescape() {
|
|
local s="$1" out="" ch code escape='^([^\\]*)\\([0-9][0-9][0-9]|.)(.*)$'
|
|
while [[ "$s" =~ $escape ]]; do
|
|
out+="${BASH_REMATCH[1]}"
|
|
code="${BASH_REMATCH[2]}"
|
|
s="${BASH_REMATCH[3]}"
|
|
if [[ "$code" == [0-9][0-9][0-9] ]]; then
|
|
# shellcheck disable=SC2059
|
|
printf -v ch "\\$(printf %03o "$((10#$code))")"
|
|
out+="$ch"
|
|
else
|
|
out+="$code"
|
|
fi
|
|
done
|
|
echo "$out$s"
|
|
}
|
|
|
|
# This machine's own .local name, which mdns_hosts leaves out
|
|
mdns_own_host() {
|
|
echo "$(hostnamectl hostname 2> /dev/null || cat /etc/hostname).local"
|
|
}
|
|
|
|
# The other machines on the network: one .local name per line
|
|
mdns_hosts() {
|
|
local own
|
|
own="$(mdns_own_host)"
|
|
mdns_services | cut -d'|' -f3 | grep -vixF "$own" | sort -u
|
|
}
|