#!/bin/sh

# this file maintained at http://git.mdcc.cx/uruk.git

# /lib/uruk/init/autodetect-ips - set variables ip{,6}_<interface>_default and
#   net{,6}_<interface>_default.  see uruk-rc(5) and the sample uruk rc file
#   as shipped with uruk in doc/rc.

# Copyright © 2012 Wessel Dankers
# Copyright © 2013 Casper Gielen
# Copyright © 2013, 2018 Joost van Baal-Ilić

# This file 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 3 of the License, or (at your option)
# any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU GPL for more details.
#
# You should have received a copy of the GNU GPL along with this file, see
# e.g. the file named COPYING.  If not, see <http://www.gnu.org/licenses/>.

# Usage: make sure your /etc/uruk/rc has leading line
# ". /lib/uruk/init/autodetect-ips", e.g. by running
#
#  sed -i '1i. /lib/uruk/init/autodetect-ips' /etc/uruk/rc
#
# Debugging:
# ~$ sh
# ~$ set -x
# ~$ . /lib/uruk/init/autodetect-ips
# ~$ set | egrep ip6\|ip_
#

###############################################
# assign IPs and networks to network interfaces
###############################################

# FIXME
# set $interfaces dynamically too?

# For each interface <if> in interfaces, ip_<if> should be defined.

# First try Red Hat's init scripts

# This works fine with dash.  (As long as you don't have a file called
# 'ifcfg-*'.)  Other non-strict shells (zsh, e.g.) might print an error "no
# matches found: /etc/sysconfig/network-scripts/ifcfg-*"

# this script will NOT work with ancient bash 3.2

for f in /etc/sysconfig/network-scripts/ifcfg-*
do
    test -e $f || continue
    iface=${f#/etc/sysconfig/network-scripts/ifcfg-}
    case $iface in *[!a-zA-Z0-9_]*|[!a-zA-Z_]*)
        continue
    esac
    eval "$(
        . $f
        echo ip_${iface}_default=$IPADDR
        echo net_${iface}_default=$IPADDR/$NETMASK
        echo ip6_${iface}_default=${IPV6ADDR%/*}
        echo net6_${iface}_default=$IPV6ADDR
    )"
done

# Second, Debian's init scripts
if test -f /etc/network/interfaces
then
    eval "$(
        while read -r key val val1 rest
        do
            case $key in iface)
                case $val in *[!a-zA-Z0-9_]*|[!a-zA-Z_]*)
                        iface=
                        type=
                ;; *)
                        iface=$val
                        type=$val1
                esac
                address=
                netmask=
                case $type in inet6)
                    netmask=64
                esac
            ;; address)
                    address=$val
                    case $address in */*)
                        netmask=${address##*/}
                        address=${address%/*}
                    esac
            ;; netmask)
                    netmask=$val
            esac
            case $iface,$address,$netmask in ?*,?*,?*)
                case $type in inet)
                    echo ip_${iface}_default=$address
                    echo net_${iface}_default=$address/$netmask
                ;; inet6)
                    echo ip6_${iface}_default=$address
                    echo net6_${iface}_default=$address/$netmask
                esac
                iface=
                type=
                address=
                netmask=
            esac
        done </etc/network/interfaces
    )"
fi

# now, parse output from ip(8).  We might find more interfaces and more IPs.
# E.g. IPs assigned not using interfaces or ifcfg-*, but instead assigned via
# udev.  We might also find runtime configuration which differs from what
# we've found in /etc/ : we go with runtime in such a case.

# if we haven't set any variables, try something like this dynamic trick:
# (beware, untested code)
#ip a | while read -r num iface rest
#   do
#    case $num in [0-9]*:) echo $iface
#    esac
#  done

if command -v ip >/dev/null 2>&1
then
    eval "$(
iface=
# jeden dva tri četiri pet ostalo
ip a | \
  while read -r jeden dva tri cetiri ostalo
  do
    case $jeden in
      [0-9]*:)
        iface=${dva%:}
      ;;
      inet)
        # deal with
        #  inet 137.56.246.197/24 brd 137.56.246.255 scope global eth0
        #  inet 137.56.246.200/24 brd 137.56.246.255 scope global secondary eth0:1
        # and
        #  inet 169.254.102.80/16 brd 169.254.255.255 scope global eth1:1
        # and
        #  inet 137.56.208.53/32 scope global deprecated nodad eth0
        case $ostalo in
          *:*|*deprecated*)
            :
          ;;
          *)
            # this kinda works, too:
            #  "scope global *")
            address=${dva%/*}
            netmask=${dva#*/}
            echo ip_${iface}_default=$address
            echo net_${iface}_default=$address/$netmask
        esac
      ;;
      inet6)
        # test scope
        if test global = $cetiri
        then
          address=${dva%/*}
          netmask=${dva#*/}
          echo ip6_${iface}_default=$address
          echo net6_${iface}_default=$address/$netmask
        fi
      ;;
    esac
  done
  )"
else
  cat <<EOT >&2
autodetecs-ips: command 'ip' not found.  might have missed to autodetect some
IPs. please install the iproute package.
EOT
fi

#(if we want to depend upon awk:
# ip a | awk '/^[0-9]:/ { print $2; exit }'
#)
