#!/bin/sh
# sg-netbrowse computers OUT | shares OUT SERVER | shares2 OUT SERVER
#
# What File Explorer's Network folder shows (wine-sg 0469), one name per line
# in OUT (UTF-8), for the signed-in user:
#   computers  the computers on the local network: those that announce file
#              sharing over mDNS (Samba, Macs, NASes -- avahi) and those that
#              answer NetBIOS name queries (Windows PCs)
#   shares     SERVER's shared folders (smbclient; the user's Kerberos ticket
#              on a domain, else as a guest). Hidden shares (ending in $),
#              as Windows hides them.
#   shares2    the same, each "name<TAB>comment" (the share's comment, as
#              the server gives it): File Explorer's Comments column (wine-sg
#              1471). An older sg-netbrowse exits 2 for it, unknown.
# Always exits 0: an empty list is an answer.
#
# SPDX-License-Identifier: AGPL-3.0-or-later
set -u
what=${1:-}; out=${2:-}
[ -n "$out" ] || { echo "usage: sg-netbrowse computers OUT | shares OUT SERVER | shares2 OUT SERVER" >&2; exit 2; }
tmp="$out.tmp"
: > "$tmp"
case "$what" in
shares|shares2)
    server=${3:-}
    case "$server" in ''|-*|*[!A-Za-z0-9._-]*) mv "$tmp" "$out"; exit 0 ;; esac
    auth=-N
    if [ -r /etc/stained-glass/role ] && grep -q '^realm=.' /etc/stained-glass/role && klist -s 2>/dev/null; then auth=--use-kerberos=required; fi
    # smbclient -g: Disk|name|comment (a comment may hold a | of its own)
    timeout 10 smbclient -g -L "//$server" "$auth" 2>/dev/null |
        awk -F'|' -v comments="$([ "$what" = shares2 ] && echo 1)" '
            $1 == "Disk" && $2 !~ /\$$/ {
                if (!comments) { print $2; next }
                c = $3; for (i = 4; i <= NF; i++) c = c "|" $i
                gsub(/[\t\r]/, " ", c)
                print $2 "\t" c
            }' >> "$tmp"
    ;;
computers)
    {
        if command -v avahi-browse >/dev/null; then
            timeout 4 avahi-browse -tpr _smb._tcp 2>/dev/null | awk -F';' '$1 == "=" { print $7 }' | sed 's/\.local$//'
        fi
        if command -v nmblookup >/dev/null; then
            for ip in $(timeout 4 nmblookup '*' 2>/dev/null | awk '/<00>/ { print $1 }'); do
                timeout 2 nmblookup -A "$ip" 2>/dev/null | awk '/<00> -/ && !/<GROUP>/ { print $1; exit }'
            done
        fi
    } | tr '[:lower:]' '[:upper:]' | grep -E '^[A-Z0-9._-]+$' | sort -u >> "$tmp"
    ;;
*)
    rm -f "$tmp"; echo "sg-netbrowse: unknown request $what" >&2; exit 2 ;;
esac
mv "$tmp" "$out"
exit 0
