#!/bin/bash
# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
source "$(dirname "$0")/lib/ulib/ulib" || exit 1
urequire DEFAULTS debian

function display_help() {
    uecho "$scriptname: gérer la configuration du réseau

USAGE
    $scriptname -c network.conf
    $scriptname [iface:]ip[/suffix]...

OPTIONS
    -P, --partial
        Activer le mode de configuration partielle. C'est la valeur par défaut.
        Dans ce mode, la configuration courante n'est pas modifiée. Seules de
        nouvelles adresses ips sont configurées le cas échéant.
    -F, --full
        Activer le mode de configuration complète. Dans ce mode, le nom d'hôte
        ainsi que toutes les interfaces, pont et adresses sont configurés.
    -z, --reset
        En mode full, recréer le fichier /etc/network/interfaces au lieu
        d'essayer de le mettre à jour.
    -l, --inline
        Prendre la configuration depuis la ligne de commande. C'est la valeur
        par défaut, sauf si un fichier network.conf existe dans le répertoire
        courant.
        Dans ce mode, chaque argument est une spécification d'adresse IP à
        configurer. Les autres paramètres i.e les ponts, le nom d'hôte et le
        contenu du fichier /etc/networks sont spécifiés avec les options -b,
        -h et -e
    -c, --config CONFIG
        Spécifier le fichier de configuration à utiliser pour la configuration
        du réseau. Cette option est automatiquement activée si le répertoire
        courant contient un fichier network.conf
    -w, --write
        Ecrire la configuration actuelle dans le fichier network.conf
        Note: comme ce script demande les droits de root, le fichier sera écrit
        avec le propriétaire root.
    -b, --bridge BR:IFACES
        En mode inline, spécifier une liste de ponts à configurer.
    -h, --host HOST
        En mode inline, spécifier le nom d'hôte pleinement qualifié
    -e, --etc-networks CONTENT
        Spécifier un contenu pour remplacer le fichier /etc/networks"
}

mode=partial
reset=
source=auto
config=
write=
brs=()
host=
etc_networks=
args=(
    --help '$exit_with display_help'
    -P,--partial mode=partial
    -F,--full mode=full
    -z,--reset reset=1
    -l,--inline source=inline
    -c:,--config: '$set@ config; source=config'
    -w,--write write=1
    -b:,--bridge: brs
    -h:,--host: host=
    -e:,--etc-networks: etc_networks=
)
parse_args "$@"; set -- "${args[@]}"

# vérification du système
check_sysinfos -d debian || die "Ce script n'est supporté que sur debian linux"

# relancer en root
args=()

case "$mode" in
p|partial) mode=partial; array_add args --partial;;
f|full) mode=full; array_add args --full;;
*) die "$mode: mode invalide. ce doit être full ou partial";;
esac
[ "$mode" == full ] || reset=
[ -n "$reset" ] && array_add args --reset

if [ "$source" == auto ]; then
    if [ -f network.conf ]; then
        estepi "Chargement automatique de network.conf"
        source=config
        config=network.conf
    else
        source=inline
    fi
fi
case "$source" in
i|inline)
    ips=("$@")
    ;;
c|config)
    [ -f "$config" ] || die "$config: fichier introuvable"
    eval "$(
      ips=(); brs=(); host=
      source "$config" >&/dev/null
      set_array_cmd ips
      set_array_cmd brs
      echo_setv host "$host"
      echo_setv etc_networks "$etc_networks"
    )"
    ;;
esac
array_add args --inline
for br in "${brs[@]}"; do
    array_add args --bridge "$br"
done
[ -n "$host" ] && array_add args --host "$host"
[ -n "$write" ] && array_add args --write
array_add args "${ips[@]}"

run_as_root "${args[@]}"

# (re)configurer le réseau
modified=
if [ "$mode" == full ]; then
    enote "La configuration COMPLETE suivante va être appliquée
    brs: ${brs[*]}
    ips: ${ips[*]}
    host: $host"
    ask_yesno "Voulez-vous continuer?" O || die
    if [ ${#ips[*]} -gt 0 -o ${#brs[*]} -gt 0 -o -n "$hosts" ]; then
        network_config "$host" ips brs "" "$reset" && modified=1
    fi
    [ -n "$etc_networks" ] && network_update_etc_networks "$etc_networks"
    [ -n "$modified" ] && eimportant "Vous devriez redémarrer le serveur pour prendre en compte la nouvelle configuration"

elif [ "$mode" == partial ]; then
    enote "La configuration PARTIELLE suivante va être appliquée
    ips: ${ips[*]}"
    ask_yesno "Voulez-vous continuer?" O || die
    if [ ${#ips[*]} -gt 0 ]; then
        network_config_partial ips && modified=1
    fi
fi

# Ecrire le fichier de configuration
if [ -n "$write" ]; then
    if [ -f network.conf ]; then
        ask_yesno "Le fichier network.conf existe. Voulez-vous l'écraser?" N || die
    fi

    network_set_confbrs brs
    network_set_confips ips
    network_fix_confs brs ips
    [ -n "$host" ] || setx host=hostname -f

    estep "network.conf"
    echo >network.conf "# -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8

# Liste des ponts à configurer. Chaque élément est de la forme BR:IFACES
# BR est le nom du pont, e.g. br0. IFACES est une liste d'interfaces séparées
# par une virgule. e.g. br0:eth0,eth1
$(set_array_cmd brs)

# Liste des adresses IPs à configurer. Chaque élément est de la forme
# [IFACE:]dhcp ou [[IFACE][//GATEWAY]:]IP[/SUFFIX]
$(set_array_cmd ips)

# Nom d'hôte pleinement qualifié. Si ce paramètre est spécifié, les fichiers
# /etc/hosts, /etc/hostname et /etc/mailname sont mis à jour.
$(echo_setv host "$host")

# Contenu du fichier /etc/networks
$(echo_setv etc_networks "$etc_networks")"
fi
