#! /bin/sh
#----------------------------------------------------------------------------
# samba-netsend - send message to SMB Hosts                        3.x.x
#
# Copyright (c) 2005 Thomas Bork, tom(at)fli4l(dot)de
#
# usage: samba-netsend
#    or: samba-netsend {all|active|"host1 host2 ..."} "message"
#
# Creation   : 04.11.2001  tb
# Last Update: $Id: samba-netsend 10586 2005-12-09 19:43:14Z knuffel $
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#----------------------------------------------------------------------------
#set -x
case $#
in
  0)
    interactive='true'
    hosts=''
    message=''
    broadcast=''
    ;;
  2)
    interactive='false'
    hosts="$1"
    message="$2"
    broadcast=''
    ;;
  *)
    echo "usage: `basename $0`" >&2
    echo "   or: `basename $0` {all|active|\"host1 host2 ...\"} \"message\"" >&2
    exit 1
    ;;
esac

colechobin="/usr/local/bin/colecho"
smbclientbin="/bin/smbclient -s /etc/smb.conf"
nmblookupbin="/bin/nmblookup -s /etc/smb.conf"

if [ -f /boot/rc.cfg ]
then
    . /boot/rc.cfg
fi

if [ "$LOCALE" = "de" ]
then
    on="auf"

    do_title ()
    {
     clrhome
     $colechobin "Sende Nachrichten an SMB Host" gn
     echo
    }

    do_askhosts ()
    {
     echo "An welche SMB Hosts soll die Nachricht gesendet werden?"
     echo
     echo "Auswahl 1"
     echo "---------"
     echo "Alle SMB-Hosts in konfigurierten Subnetzen von fli4l - gebe 'all' ein."
     echo
     echo "Auswahl 2"
     echo "---------"
     echo "fli4l-Samba-Clients mit aktiven Verbindungen - gebe 'active' ein."
     echo
     echo "Auswahl 3"
     echo "---------"
     echo "Ein oder mehrere aktive SMB-Hosts, gebe die NETBIOS-Namen mit einem"
     echo "Leerzeichen getrennt ein, z.B. 'client1 client2':"
    }

    do_emptyhosts ()
    {
     $colechobin "Kein Host angegeben" br x br
    }

    do_message ()
    {
     echo "Welche Nachricht soll gesendet werden?"
     echo "z.B. 'fli4l-Samba-Server wird in 3 Minuten heruntergefahren...':"
    }

    do_emptymessage ()
    {
     $colechobin "Keine Nachricht angegeben" br x br
    }

    do_broadcast ()
    {
     $colechobin "Sende Nachrichten auf Broadcast-Adresse $y..." bl x br
    }

    do_emptyactive ()
    {
     $colechobin "Kein fli4l-Samba-Client aktiv" br x br
    }

    do_sendmessageinfo ()
    {
     echo "Sende Nachricht an NETBIOS-Name $name ($i)..."
    }

    do_sendmessageinfofailed ()
    {
     $colechobin "Senden der Nachricht an NETBIOS-Name $name ($i) fehlgeschlagen" br x br
    }

    do_sendmessageinfoipfailed ()
    {
     $colechobin "Senden der Nachricht an NETBIOS-Name $name fehlgeschlagen (keine IP gefunden)" br x br
    }
else
    on="on"

    do_title ()
    {
     clrhome
     $colechobin "Send message to SMB hosts" gn
     echo
    }

    do_askhosts ()
    {
     echo "To which SMB hosts the message should be send?"
     echo
     echo "Choice 1"
     echo "--------"
     echo "All SMB hosts on configured subnets on fli4l - type 'all'."
     echo
     echo "Choice 2"
     echo "--------"
     echo "fli4l Samba clients with active connections - type 'active'."
     echo
     echo "Choice 3"
     echo "--------"
     echo "One ore more active SMB hosts, type NETBIOS names"
     echo "separated with a blank, for instance 'client1 client2':"
    }

    do_emptyhosts ()
    {
     $colechobin "No host specified" br x br
    }

    do_message ()
    {
     echo "Which message should be send?"
     echo "For instance 'fli4l samba server is going down in 3 minutes...':"
    }

    do_emptymessage ()
    {
     $colechobin "No message specified" br x br
    }

    do_broadcast ()
    {
     $colechobin "Sending messages on broadcast address $y..." bl x br
    }

    do_emptyactive ()
    {
     $colechobin "No fli4l Samba client active" br x br
    }

    do_sendmessageinfo ()
    {
     echo "Sending message to netbios name $name ($i)..."
    }

    do_sendmessageinfofailed ()
    {
     $colechobin "Sending message to netbios name $name ($i) failed" br x br
    }

    do_sendmessageinfoipfailed ()
    {
     $colechobin "Sending message to netbios name $name failed (no ip found)" br x br
    }
fi

from="fli4l-samba-server $on `hostname`"

do_sendmessage ()
{
   if [ "$name" != "$hostname" -a "$name" != "" ]
   then
       ip=`$nmblookupbin $name                    \
       | grep -v "querying "                      \
       | grep -v "name_query failed to find name" \
       | cut -d" " -f1`

       if [ "$ip" != "" ]
       then
           for i in $ip
           do
             if [ "$i" != "" ]
             then
                 do_sendmessageinfo
                 echo "$message" | $smbclientbin -U "$from" -M "$name" -I "$i" 1> /dev/null

                 if [ "$?" != "0" ]
                 then
                     do_sendmessageinfofailed
                 fi
             fi
           done
       else
           do_sendmessageinfoipfailed
       fi
   fi	
}

if [ "$interactive" = "true" ]
then
    do_title
fi

if [ "$hosts" = "" ]
then
    do_askhosts
    echo
    read hosts

    if [ "$hosts" = "" ]
    then
        echo
        do_emptyhosts
        echo
        exit 1
    fi

    hosts="`echo $hosts | tr 'A-X' 'a-x'`"
fi

if [ "$interactive" = "true" ]
then
    do_title
fi

if [ "$message" = "" ]
then
    do_message
    echo
    read message

    if [ "$message" = "" ]
    then
        echo
        do_emptymessage
        echo
        exit 1
    fi
fi

if [ "$interactive" = "true" ]
then
    do_title
fi

case "$hosts"
in
  all)
      for b in `grep " interfaces = " /etc/smb.conf | cut -c16-`
      do
        ipaddr=`echo $b | cut -d"/" -f1`
        netmask=`echo $b | cut -d"/" -f2`
        network=`netcalc network $ipaddr $netmask`
        n1=`echo $network | cut -d"." -f1`
        newbroadcast=`netcalc broadcast $network $netmask`

        case $broadcast
        in
          *$newbroadcast*)
                          ;;
                        *)
                          broadcast="$broadcast $newbroadcast"
                          ;;
        esac
      done

      hostname=`hostname | tr 'a-x' 'A-X'`

      for y in $broadcast
      do
        do_broadcast

        for z in `$nmblookupbin '*' -B $y            \
        | grep -v "Sending queries to "              \
        | grep -v "name_query failed to find name *" \
        | cut -d" " -f1`
        do
        z1=`echo $z | cut -d"." -f1`
        if [ "$z1" != "querying" ]
         then
          if [ "$z1" != "$n1" ]
           then exit 1
          fi
         fi
          name=`$nmblookupbin -A $z \
          | grep \<00\>             \
          | grep -v GROUP           \
          | grep -v 'IS~'           \
          | sed "s/ .*//"           \
          | sort -u`

          name=`echo $name \
          | sed "s/ //"    \
          | sed "s/\t//"`

          do_sendmessage
        done
      done
      ;;
active)
      status=`smbstatus -b -s /etc/smb.conf                                      \
      | grep -v "Samba version 3.0.23c"                                           \
      | grep -v "PID     Username      Group         Machine                   " \
      | grep -v "^-"                                                             \
      | grep '[1-9]' | cut -c37-51`

      if [ "$status" = "" ]
      then
          do_emptyactive
          echo
          exit 1
      else
          for name in $status
          do
            do_sendmessage
          done
      fi
      ;;
    *)
      # hosts = separate list
      for name in $hosts
      do
        do_sendmessage
      done
      ;;
esac
