#!/usr/local/bin/tclsh8.6

#
# Delete host, IP address or alias
#
# Called by: suppr
#
# Parameters (form or url):
#   - display page
#   - name or IP address removal
#	- action : "del"
#	- name & domain : name and domain of object to remove
#	- addr : IP address to remove or FQDN
#		(addr is exclusive with name & domain)
#	- idviews : selected (after confirmation) views
#
# Note:
#   If script is called for the first time, addr & name & domain are
#	empty, so the script display the selection page
#   When user inputs either a name&domain, or an addr (which may also
#	be a fqdn), all found objects (in all views) are presented
#	for confirmation
#   When some objets are selected (idviews is not empty), removal is
#	performed
#
# History
#   2002/04/11 : pda/jean : design
#   2002/05/03 : pda/jean : split 3 modification types
#   2002/07/09 : pda      : add nologin
#   2003/05/13 : pda/jean : use auth base
#   2004/01/14 : pda/jean : add IPv6
#   2004/08/05 : pda/jean : add mac
#   2005/04/08 : pda/jean : add dhcpprofile
#   2007/10/25 : jean     : log modify actions
#   2008/07/24 : pda/jean : add sendsmtp
#   2008/07/29 : pda      : use display-rr
#   2010/10/15 : pda      : add journey
#   2010/12/14 : pda      : i18n
#   2010/12/25 : pda      : use cgi-dispatch
#   2012/11/13 : pda/jean : add views
#   2012/11/14 : pda/jean : merge name and ip cases
#

#
# Template pages used by this script
#

set conf(page-sel)	del-sel.html
set conf(page-confirm)	del-confirm.html
set conf(page-ok)	del-ok.html

#
# Next actions
# 

set conf(next)		"del"
set conf(nextmap)	"net"
set conf(nextlist)	"net"
set conf(nextsearch)	"search"
set conf(nextipinact)	"ipinact"

#
# Script parameters
#

set conf(tab-confirm) {
    global {
	chars {10 normal}
	columns {5 10 85}
	align {left}
	botbar {no}
    }
    pattern Line {
	vbar {no}
	column {
	    format {raw}
	}
	vbar {no}
	column {
	    format {raw}
	}
	vbar {no}
	column {
	    format {raw}
	}
	vbar {no}
    }
}

#
# Netmagis general library
#

source /usr/local/lib/netmagis/libnetmagis.tcl

# ::webapp::cgidebug ; exit

##############################################################################
# Ask for confirmation
##############################################################################

# mode : "addr" or "host-or-alias"
# object : ip address for "addr" mode, or fqdn for "host-or-alias" mode

proc confirm {dbfd mode object _chkv} {
    global conf
    upvar $_chkv chkv

    set idviews $chkv(idviews)
    set nok [llength $chkv(ok)]

    # display checkbutton for view only if there is more than a single view
    set dispconfview [expr $nok > 1]

    # terrible hack
    set empty [::webapp::helem "span" "" "style" "display:none"]

    set lines {}
    foreach idview $idviews {
	lassign $chkv($idview) vn msg t

	set buttid "bv$idview"
	set desc $empty

	array unset trr
	array set trr $t

	if {$msg ne ""} then {
	    #
	    # Error message
	    #
	    set check ""
	    set host [::webapp::html-string $msg]
	} else {
	    #
	    # Get host information
	    #
	    lassign [display-rr-masked $dbfd trr $idview {}] link desc

	    if {$mode eq "host-or-alias"} then {
		#
		# Information about host found
		#

		set cname [rr-cname-by-view trr $idview]
		if {$cname eq ""} then {
		    # This is not an alias
		    set host [mc "Remove host '%s'" $link]
		} else {
		    # This is an alias, display informations about target host
		    set host [mc "Remove alias '%s'" $link]
		}
	    } else {
		#
		# Information about IP address found.
		# Is it the last IP address?
		#

		set lip [rr-ip-by-view trr $idview]
		if {[llength $lip] == 1} then {
		    set host [mc "Remove host '%s'" $link]
		} else {
		    set host [mc {Remove IP address '%1$s' from host '%2$s'} $object $link]
		}
	    }

	    #
	    # View name and check box
	    #

	    if {$dispconfview} then {
		set c ""
	    } else {
		set c " CHECKED"
	    }
	    set check "<INPUT TYPE=CHECKBOX NAME=\"idviews\" ID=\"$buttid\" VALUE=\"$idview\" $c>"

	    set vn [::webapp::helem "label" $vn "for" $buttid]
	}
	lappend lines [list Line $check $vn $host]
	lappend lines [list Line $empty $empty $desc]
    }

    set seldel [::arrgen::output "html" $conf(tab-confirm) $lines]

    #
    # Other parameters
    #

    set hidden [::webapp::form-hidden "addr" $object]

    #
    # Confirmation needed
    #

    d urlset "%URLFORM%" $conf(next) {}
    d urladdnext "%URLFORM%"

    d result $conf(page-confirm) [list \
					[list %OBJECT% $object] \
					[list %SELDEL% $seldel] \
					[list %HIDDEN% $hidden] \
				    ]
}

##############################################################################
# Process removal
##############################################################################

# mode : "addr" or "host-or-alias"
# object : ip address for "addr" mode, or fqdn for "host-or-alias" mode

proc remove {dbfd mode object _chkv} {
    global conf
    upvar $_chkv chkv

    set idviews $chkv(idviews)

    #
    # Confirmation is accepted. All view ids have been checked.
    # Do the removal.
    #

    d dblock {}

    set result {}
    foreach idview $idviews {
	lassign $chkv($idview) vn msg t

	array unset trr
	array set trr $t

	if {$mode eq "host-or-alias"} then {
	    set delobj $object
	    set msg [del-host $dbfd trr $idview]
	    if {$msg ne ""} then {
		d dbabort [mc "delete %s" $object/$vn] $msg
	    }
	} else {
	    set msg [del-ip $dbfd $object trr $idview delobj]
	    if {$msg ne ""} then {
		d dbabort [mc "delete %s" $object/$vn] $msg
	    }
	}
	lappend result [mc {'%1$s' has been removed from view '%2$s'} $delobj $vn]
    }

    d dbcommit [mc "delete %s" $object]

    #
    # Prepare next step in journey
    #

    switch -- [d nextprog] {
	search {
	    d urlset "%URLSUITE%" $conf(nextsearch) [list [d nextargs]]
	}
	map {
	    d urlset "%URLSUITE%" $conf(nextmap) [list {domap {yes}} [d nextargs]]
	}
	list {
	    d urlset "%URLSUITE%" $conf(nextlist) [list {dolist {yes}} [d nextargs]]
	}
	ipinact {
	    d urlset "%URLSUITE%" $conf(nextipinact) [list [d nextargs]]
	}
	default {
	    d urlset "%URLSUITE%" $conf(next) {}
	}
    }

    #
    # End of script: output page and close database
    #

    set result [join $result "<br>"]

    d result $conf(page-ok) [list \
				    [list %RESULT% $result] \
			]
}

##############################################################################
# CGI script
##############################################################################

# History
#   2002/04/19 : pda/jean : design
#

d cgi-register {} {
    {addr	0 1}
    {name	0 1}
    {domain	0 1}
    {idviews	0 9999}
} {
    global conf

    #
    # Display the selection page if no parameter is given
    #

    if {$addr eq "" && $name eq "" && $domain eq ""} then {
	#
	# Get domains authorized for the user
	#

	set domain [menu-domain $dbfd $tabuid(idcor) "domain" "" ""]

	#
	# End of script: output page and close database
	#

	d urlset "%URLFORM%" $conf(next) {}
	d result $conf(page-sel) [list \
				    [list %DOMAIN% $domain] \
				]
	return 0
    }

    #
    # Addr and name/iddom are mutually exclusive
    #

    if {$addr ne "" && ($name ne "" || $domain ne "")} then {
	d error [mc "Invalid input"]
    }

    #
    # Check wether it is an address (which may be a FQDN) or name+domain
    #

    if {$addr ne ""} then {
	set object $addr
	set msg [check-ip-syntax $dbfd $addr "inet"]
	if {$msg ne ""} then {
	    #
	    # This is not an IP address. It is perhaps a FQDN
	    #
	    set msg [check-fqdn-syntax $dbfd $addr name domain]
	    if {$msg ne ""} then {
		d error $msg
	    }
	    set addr ""
	} else {
	    #
	    # This is an IP address. Check it.
	    #
	    if {! [check-authorized-ip $dbfd $tabuid(idcor) $addr]} then {
		d error [mc "You don't have rights on '%s'" $addr]
	    }
	}
    } else {
	# Check that name is not empty, or wrong domain
	set msg [check-fqdn-syntax $dbfd "$name.$domain" name domain]
	if {$msg ne ""} then {
	    d error $msg
	}
    }

    #
    # Identify proprer mode for later usage
    #

    if {$addr eq ""} then {
	set mode "host-or-alias"
	set object "$name.$domain"
    } else {
	set mode "addr"
	set object $addr
    }

    #
    # Filter view ids
    #

    set msg [filter-views $dbfd tabuid $mode $object $idviews chkv]
    if {$msg ne ""} then {
	d error $msg
    }

    #
    # Ask for confirmation if needed
    #

    if {[llength $idviews] == 0} then {
	confirm $dbfd $mode $object chkv
    } else {
	remove $dbfd $mode $object chkv
    }
}

##############################################################################
# Main procedure
##############################################################################

d cgi-dispatch "dns" ""
