#!/bin/sh

po_domain="alterator-bind"
bindconffile="/var/lib/bind/etc/options.conf"

ipregexp="([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])([.]([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9+]|25[0-5])){3}"
maskregexp="(/[0-9]|/[12][0-9]|/3[0-2])?"
netregexp="^($ipregexp$maskregexp|none|localhost|any|localnets)$"

#turn off auto expansion
set -f

alterator_api_version=1
. alterator-sh-functions

PATH="/usr/lib/alterator-bind/:$PATH"

### forwarders / allow-query / allow-recursion
avail_objects()
{
    sed -nr "/^[[:space:]]*$1/ {s,.*\{([^\}]*)\}.*,\1,;p}" "$bindconffile"|
	tr ';' '\n'|
        sed -r 's,[[:space:]]*([/a-z0-9\.]+).*,\1,
		/^[[:space:]]*$/ d'
}

delete_objects()
{
    sed -r "s,^([[:space:]]*$1.*)[[:space:]]*$2[[:space:]]*;(.*),\1\2," -i "$bindconffile"
}

new_objects()
{
    sed -r "s,^([[:space:]]*//[[:space:]]*$1)[[:space:]]*.*,\1 {};," -i "$bindconffile"
    sed -r "s,^([[:space:]]*)(//)?([[:space:]]*$1)[[:space:]]*\{([^}]*)\},\1\3 {\4$2;}," -i "$bindconffile"
}

### forward

read_forward()
{
    sed -nr '/^[[:space:]]*forward[[:space:]]/ {s,^[[:space:]]*forward[[:space:]]+([a-z]+).*,\1,;p}' "$bindconffile"
}

write_forward()
{
    sed -r "s,^([[:space:]]*)(//)?forward[[:space:]]+.*,\1forward $1;," -i "$bindconffile"
}

### config normalization
fix_config()
{
    #try to fix config if we need it
    normalize_config "$bindconffile" >"$bindconffile.new"
    if cmp "$bindconffile" "$bindconffile.new" >&2 ;then
        rm -f "$bindconffile.new"
    else
        chown root:named "$bindconffile.new"
        chmod 640 "$bindconffile.new"
        mv -f "$bindconffile.new" "$bindconffile"
    fi
}


net_required()
{
    if [ "$in_orig_action" = "new" ] &&  [ "$in_type" = "allow-query" -o "$in_type" = "allow-recursion" ] ;then
	echo "#t"
    else
	echo "#f"
    fi
}

### initial actions
fix_config

on_message() {
case "$in_action" in
  constraints)
    printf 'new_forwarder (label "%s" ipv4-address #t)' \
      "`_ "Forwarding server"`" >&3
    printf 'new_allow_query (label "%s"  match ("%s" "%s"))' \
      "`_ "Network address"`" \
      "$netregexp" \
      "`_ "Invalid network address"`" >&3
    printf 'new_allow_recursion (label "%s"  match ("%s" "%s"))' \
      "`_ "Network address"`" \
      "$netregexp" \
      "`_ "Invalid network address"`" >&3
    ;;
  list)
    case "$in__objects" in
      forwarders|allow-query|allow-recursion)
        avail_objects "$in__objects" | write_enum
        ;;
      forward)
        write_enum_item first "`_ "first"`"
        write_enum_item only  "`_ "only"`"
        ;;
    esac
    ;;
  read)
    write_string_param forward "$(read_forward)"
    ;;
  write)
    if [ -n "$in_general" ]; then
      [ -n "$in_forward" ] && write_forward "$in_forward"
      return
    fi

    local type=
    local name=
    local action=
    if   [ -n "$in_add_forwarder" -a -n "$in_new_forwarder" ]; then
      action=add; type=forwarders; name=$in_new_forwarder
    elif [ -n "$in_add_allow_query" -a -n "$in_new_allow_query" ]; then
      action=add; type=allow-query; name=$in_new_allow_query
    elif [ -n "$in_add_allow_recursion" -a -n "$in_new_allow_recursion" ]; then
      action=add; type=allow-recursion; name=$in_new_allow_recursion
    elif [ -n "$in_del_forwarder" -a -n "$in_forwarder" ]; then
      action=del; type=forwarders; name=$in_forwarder
    elif [ -n "$in_del_allow_query" -a -n "$in_allow_query" ]; then
      action=del; type=allow-query; name=$in_allow_query
    elif [ -n "$in_del_allow_recursion" -a -n "$in_allow_recursion" ]; then
      action=del; type=allow-recursion; name=$in_allow_recursion
    fi

    if [ "$action" = add -a -n "$name" -a -n "$type" ]; then
      if avail_objects $type | grep -qs "^$name$"; then
        write_error "`_ "Same IP/Network already exists"`"
        return
      fi
      new_objects "$type" "$name"
    elif [ "$action" = del -a -n "$name" -a -n "$type" ]; then
      delete_objects "$type" "$name"
    fi
    ;;
  esac
}

message_loop
