# shroudBNC - an object-oriented framework for IRC
# Copyright (C) 2005 Gunnar Beutner
#
# Modified by Khobbits
#
# 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.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

internalbind command virtual:commandiface

###########################################################
#### Edit these next two lines depending on preference ####
###########################################################

set ::vsbncserver [list irc.SwiftIRC.net 6667]
set ::vsbncdeluser 1

proc virtual:commandiface {client parameters} {
	if {![virtual:isadmin $client] && ![getbncuser $client admin]} { return }

	set command [lindex $parameters 0]

	if {[getbncuser $client admin]} {
		if {[string equal -nocase $command "addgroup"]} { virtual:cmd:addgroup $client $parameters }
		if {[string equal -nocase $command "delgroup"]} { virtual:cmd:delgroup $client $parameters }
		if {[string equal -nocase $command "vadmin"]} { virtual:cmd:vadmin $client $parameters }
		if {[string equal -nocase $command "vunadmin"]} { virtual:cmd:vunadmin $client $parameters }
		if {[string equal -nocase $command "getlimit"]} { virtual:cmd:getlimit $client $parameters }
		if {[string equal -nocase $command "setlimit"]} { virtual:cmd:setlimit $client $parameters }
		if {[string equal -nocase $command "setgroup"]} { virtual:cmd:setgroup $client $parameters }
		if {[string equal -nocase $command "unsetgroup"]} { virtual:cmd:unsetgroup $client $parameters }
		if {[string equal -nocase $command "groups"]} { virtual:cmd:groups $client $parameters }
	} else {
		if {[string equal -nocase $command "getlimit"]} { virtual:cmd:getlimit $client $parameters }
	}

	if {[string equal -nocase $command "who"]} { virtual:cmd:who $client $parameters }
	if {[string equal -nocase $command "resetpass"]} { virtual:cmd:resetpass $client $parameters }
	if {[string equal -nocase $command "deluser"]} { virtual:cmd:deluser $client $parameters }
	if {[string equal -nocase $command "adduser"]} { virtual:cmd:adduser $client $parameters }

	if {[string equal -nocase $command "help"]} {
		if {[getbncuser $client admin]} {
			bncaddcommand "addgroup" "VAdmin" "creates a new group" "Syntax: adduser <User> <Password> \[Group\]"
			bncaddcommand "delgroup" "VAdmin" "deletes a group and all its users" "Syntax: delgroup <Group>"
			bncaddcommand "vadmin" "VAdmin" "gives a user virtual admin privileges" "Syntax: vadmin <User>"
			bncaddcommand "vunadmin" "VAdmin" "removes a user's virtual admin privileges" "Syntax: vunadmin <User>"
			bncaddcommand "getlimit" "VAdmin" "gets a group's limit" "Syntax: getlimit \[Group\]"
			bncaddcommand "setlimit" "VAdmin" "sets a group's limit" "Syntax: setlimit <Group> <Limit>"
			bncaddcommand "setgroup" "VAdmin" "defines which group a user belongs, can be used to create group from existing users. (KH)" "Syntax: setgroup <User> <Group>\nMake group the same as user to create group from user."
			bncaddcommand "unsetgroup" "VAdmin" "Removes a user from a group. (KH)" "Syntax: unsetgroup <User>"
			bncaddcommand "groups" "VAdmin" "lists all groups" "Syntax: groups"

			set help "Syntax: who \[group\]\n"
			append help "Shows a list of all users (in a specific group).\n"
			append help "Flags (which are displayed in front of the username):\n"
			append help "@ user is an admin\n"
			append help "\$ user is a virtual admin"
			append help "* user is currently logged in\n"
			append help "! user is suspended\n"
			bncaddcommand "who" "Admin" "shows users" $help
		} else {
			bncaddcommand "adduser" "VAdmin" "creates a new user" "Syntax: adduser <username> <password>\nCreates a new user."
			bncaddcommand "deluser" "VAdmin" "removes a user" "Syntax: deluser <username>\nDeletes a user."
			bncaddcommand "resetpass" "VAdmin" "sets a user's password" "Syntax: resetpass <user> <password>\nResets another user's password."
			bncaddcommand "getlimit" "VAdmin" "gets your group's limit" "Syntax: getlimit"

			set help "Syntax: who\n"
			append help "Shows a list of all users.\n"
			append help "Flags (which are displayed in front of the username):\n"
			append help "@ user is an admin\n"
			append help "\$ user is a virtual admin"
			append help "* user is currently logged in\n"
			append help "! user is suspended\n"
			bncaddcommand "who" "VAdmin" "shows users" $help
		}
	}
}

proc virtual:isadmin {account} {
	if {[getbncuser $account tag reseller] == "1"} {
		return 1
	} else {
		return 0
	}
}

proc virtual:getacc {account} {

	catch {lsearch -inline -regex [bncuserlist] "(?i)^${account}$"} result
	if {$result != ""} {
		return $result
	} else {
		return 0
	}

}

proc virtual:setadmin {group account {value 1}} {
	setbncuser $account tag group $group
	setbncuser $account tag reseller $value
}

proc virtual:getadmin {group} {
	foreach user [bncuserlist] {
		if {[virtual:isadmin $user] && [string equal -nocase [virtual:getgroup $user] $group] && [getbncuser $user tag maxbncs] != ""} {
			return $user
		}
	}

	return ""
}

proc virtual:setgroup {account group} {
	setbncuser $account tag group $group
}

proc virtual:getgroup {account} {
	variable result

	set error [catch [list getbncuser $account tag group] result]

	if {$error} { return "" }

	return $result
}

proc virtual:setmaxbncs {group maxbncs} {
	set account [virtual:getadmin $group]

	if {$account == ""} { return 0 }

	setbncuser $account tag maxbncs $maxbncs

	return 1
}

proc virtual:getmaxbncs {group} {
	set account [virtual:getadmin $group]

	if {$account == ""} { return 0 }

	return [getbncuser $account tag maxbncs]
}

proc virtual:cmd:who {account parameters} {
	set accts [getctx 1]

	if {[getbncuser $account admin]} {
		set group [lindex $parameters 1]
	} else {
		set group [virtual:getgroup $account]
	}

	foreach user [lsort [bncuserlist]] {
		if {[string equal -nocase [virtual:getgroup $user] $group] || $group == ""} {
			set out ""

			setctx $user

			if {[getbncuser $user admin]} {
				append out "@"
			}

			if {[virtual:isadmin $user]} {
				if {[getbncuser $account admin]} {
					append out "\$"
				} else {
					append out "@"
				}
			}

			if {[getbncuser $user hasclient]} {
				append out "*"
			}

			if {[getbncuser $user lock]} {
				append out "!"
			}

			append out $user
			append out "([getcurrentnick])@[getbncuser $user client] \[[getbncuser $user realserver]\]"

			append out " \[Last seen: "

			if {[getbncuser $user hasclient]} {
				append out "Now"
			} elseif {[getbncuser $user seen] == 0} {
				append out "Never"
			} else {
				append out [strftime "%c" [getbncuser $user seen]]
			}

			append out "\]"

			if {[getbncuser $account admin] && $group == ""} {
				set grp [virtual:getgroup $user]
				if {$grp == ""} { set grp "<none>" }
				append out " $grp"
			}

			append out " :[getbncuser $user realname]"

			setctx $account
			bncreply $out
		}
	}

	bncreply "End of USERS."

	haltoutput
}

# 0 - ok
# -1 - human readable error
proc virtual:vresetpass {caller user pass} {
	if {![getbncuser $caller admin] && ![string equal -nocase [virtual:getgroup $caller] [virtual:getgroup $user]]} {
		return [list -1 "There's no such user."]
	}

	setbncuser $user password $pass

	return [list 0]
}

proc virtual:cmd:resetpass {client parameters} {
	set user [lindex $parameters 1]
	set pass [lindex $parameters 2]

	if {$pass == ""} {
		bncreply "Syntax: resetpass <User> <Password>"
		haltoutput

		return
	}

	set result [virtual:vresetpass $client $user $pass]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput

		return
	}

	bncreply "Done."
	haltoutput
}

proc virtual:cmd:setgroup {client parameters} {
	set user [lindex $parameters 1]
	set group [lindex $parameters 2]
	if {$group == ""} {
		bncreply "Syntax: setgroup <User> <Group> (make group the same as user to create group from user)"
		haltoutput

		return
	}
	catch {virtual:getacc $group} result
	if {$result != "0"} {
		set group $result
	} else {
		bncreply "No such group or user."
		haltoutput
		return
	}
	if {[getbncuser $user tag maxbncs] != ""} {
		set users [llength [virtual:vgroupusers $user]]
		if {$users > 1} {
		bncreply "You cannot move this user. This user is also a group and has $users users."
		haltoutput

		return
		}
	}

	if {[virtual:getadmin $group] == ""} {
	    if {$user == $group} {
		virtual:setadmin $group $group
		setbncuser $group tag maxbncs 1

		bncreply "No such group, creating and giving vadmin to $user (set limit to 1)."
	   } else {
		bncreply "No such group, a group needs to belong to a user."
		haltoutput

		return
	   }
	}

	set result [virtual:setgroup $user $group]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput

		return
	}

	bncreply "Done."
	haltoutput
}

proc virtual:cmd:unsetgroup {client parameters} {
	set user [lindex $parameters 1]

	if {$group == ""} {
		bncreply "Syntax: unsetgroup <User>"
		haltoutput

		return
	}

	if {[getbncuser $user tag maxbncs] != ""} {
	set users [llength [virtual:vgroupusers $user]]
		if {$users != 1} {
		bncreply "You cannot move this user. This user is also a group and has $users users."
		haltoutput

		return
		}
	}
		setbncuser $account tag group :
		setbncuser $account tag reseller :
		setbncuser $user tag maxbncs :

	bncreply "Done."
	haltoutput
}

# 0 - done
# -1 - human readable error
proc virtual:vdeluser {caller user {overridegroups 0}} {
	global vsbncdeluser

	if {[string equal -nocase $user $caller]} {
		return [list -1 "You can't remove your own account."]
	}

	if {![getbncuser $caller admin]} {
		if {![string equal -nocase [virtual:getgroup $user] [virtual:getgroup $caller]]} {
			return [list -1 "There's no such user."]
		}

		if {[getbncuser $user lock]} {
			return [list -1 "You can't remove suspended accounts."]
		}
	}

	if {!$overridegroups && [getbncuser $caller admin]} {
		if {[getbncuser $user tag maxbncs] != ""} {
			return [list -1 "You cannot remove this user. Delete the group instead if you really want to delete this user."]
		}
	}

	if {!$vsbncdeluser && ![getbncuser $caller admin]} {
		return [list -1 "Operation not permitted."]
	}

	delbncuser $user

	return [list 0]
}

proc virtual:cmd:deluser {client parameters} {
	set user [lindex $parameters 1]

	if {$user == ""} {
		bncreply "Syntax: deluser <User>"
		haltoutput
		return
	}

	set result [virtual:vdeluser $client $user]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput

		return
	}

	bncreply "Done."
	haltoutput
}

# 0 - ok
# -1 - human-readable error
# -2 - exceeding limit
proc virtual:vadduser {user pass group {checklimits 1} {override 0}} {
	global vsbncserver

	if {![string is alnum $user]} {
		return [list -1 "Sorry, the ident must be alpha-numeric."]
	}

	set error [catch [list getbncuser $user server] result]

	if {!$error} {
		return [list -1 "The ident '$user' is already in use."]
	}

	if {$override == 0 && $group != ""} {

	catch {virtual:getacc $group} result
	if {$result != "0"} {
		set group $result
	} else {
		return [list -1 "There is no such group: $group"]
	}
	}

	if {$checklimits} {
		set maxbncs [virtual:getmaxbncs $group]

		set bncs [list]
		foreach u [bncuserlist] {
			if {[string equal -nocase $group [getbncuser $u tag group]]} {
				lappend bncs $u
			}
		}

		if {[llength $bncs] >= $maxbncs} {
			return [join [list -2 [llength $bncs]]]
		}
	}

	addbncuser $user $pass
	setbncuser $user server [lindex $vsbncserver 0]
	setbncuser $user port [lindex $vsbncserver 1]
	virtual:setgroup $user $group

	if {[lsearch -exact [info commands] "vhost:autosetvhost"] != -1} {
		vhost:autosetvhost $user
	}

	return [list 0]
}

proc virtual:cmd:adduser {client parameters} {
	set user [lindex $parameters 1]
	set pass [lindex $parameters 2]

	if {[getbncuser $client admin]} {
		set group [lindex $parameters 3]
		set override 0
	} else {
		set group [virtual:getgroup $client]
		set override 0
	}

	if {$pass == ""} {
		if {[getbncuser $client admin]} {
			bncreply "Syntax: adduser <User> <Password> \[<Group>\]"
		} else {
			bncreply "Syntax: adduser <User> <Password>"
		}

		haltoutput
		return
	}

	if {[getbncuser $client admin]} {
		set checklimits 0
	} else {
		set checklimits 1
	}

	set return [virtual:vadduser $user $pass $group $checklimits $override]

	if {[lindex $return 0] == -1} {
		bncreply [lindex $return 1]
		haltoutput

		return
	}

	if {[lindex $return 0] == -2} {
		bncreply "You already have [lindex $return 1] bouncers. Ask the bouncer admin for an upgrade of your account."
		haltoutput

		return
	}

	bncreply "Done."
	haltoutput
}

# 0 - ok
# -1 - human readable error
proc virtual:vaddgroup {group limit} {
	set pass [randstring 8]

	if {![string is integer $limit]} {
		return [list -1 "Limit should be a number."]
	}

	foreach user [bncuserlist] {
		if {[string equal -nocase $group [virtual:getgroup $user]]} {
			return [list -1 "This groupname is already in use. Try /sbnc who $group to view a list of users."]
		}
	}

	set result [virtual:vadduser $group $pass $group 0 1]

	if {[lindex $result 0] == -1} {
		return $result
	}

	virtual:setadmin $group $group
	setbncuser $group tag maxbncs $limit

	return [list 0 $pass]
}

proc virtual:cmd:addgroup {client parameters} {
	set group [lindex $parameters 1]
	set limit [lindex $parameters 2]

	if {$limit == ""} {
		bncreply "Syntax: addgroup <Group> <Limit>"
		haltoutput
		return
	}

	set result [virtual:vaddgroup $group $limit]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput
		return
	}

	bncreply "Created a new group and user '$group' with password '[lindex $result 1]'."
	haltoutput
}

# 0 - ok
proc virtual:vdelgroup {group} {
	foreach user [bncuserlist] {
		if {[string equal -nocase $group [virtual:getgroup $user]] && ![getbncuser $user admin]} {
			delbncuser $user
		}
	}

	return [list 0]
}

proc virtual:cmd:delgroup {client parameters} {
	set group [lindex $parameters 1]

	if {$group == ""} {
		bncreply "Syntax: delgroup <Group>"
		haltoutput
		return
	}

	virtual:vdelgroup $group

	bncreply "Deleted all users in group '$group' (except real admins)."
	haltoutput
}

# 0 - ok
# -1 - human readable error
proc virtual:vadmin {user} {
	if {[virtual:getgroup $user] == ""} {
		return [list -1 "'$user' is not in a group."]
	}

	virtual:setadmin [virtual:getgroup $user] $user

	return [list 0]
}

proc virtual:cmd:vadmin {client parameters} {
	set user [lindex $parameters 1]

	if {$user == ""} {
		bncreply "Syntax: vadmin <User>"
		haltoutput
		return
	}

	set result [virtual:vadmin $user]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput
		return
	}

	bncreply "'$user' is now a virtual admin."
	haltoutput
}

# 0 - ok
# -1 - human readable error
proc virtual:vunadmin {user} {
	if {[virtual:getgroup $user] == ""} {
		return [list -1 "'$user' is not in a group."]
	}

	if {[getbncuser $user tag maxbncs] != ""} {
		return [list -1 "You cannot remove this user's admin privilesges. Delete the group instead.."]
	}

	virtual:setadmin [virtual:getgroup $user] $user 0

	return [list 0]
}

proc virtual:cmd:vunadmin {client parameters} {
	set user [lindex $parameters 1]

	if {$user == ""} {
		bncreply "Syntax: vunadmin <User>"
		haltoutput
		return
	}

	set result [virtual:vunadmin $user]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput
		return
	}

	bncreply "'$user' is no longer a virtual admin."
	haltoutput
}

proc virtual:cmd:getlimit {client parameters} {

	if {[getbncuser $account admin]} {
		set group [lindex $parameters 1]
	} else {
		set group [virtual:getgroup $client]
	}

	if {$group == ""} {
		bncreply "Syntax: getlimit <Group>"
		haltoutput
		return
	}

	if {[virtual:getadmin $group] == ""} {
		bncreply "'$group' is not a group."
		haltoutput
		return
	}

	bncreply "$group is limited to [virtual:getmaxbncs $group] users."
	haltoutput
}

# 0 - ok
# -1 - human readable error
proc virtual:vsetlimit {group limit} {
	if {[virtual:getadmin $group] == ""} {
		return [list -1 "'$group' is not a group."]
	}

	if {![string is integer $limit]} {
		return [list -1 "You did not specify a valid limit."]
	}

	virtual:setmaxbncs $group $limit

	return [list 0]
}

proc virtual:cmd:setlimit {client parameters} {
	set group [lindex $parameters 1]
	set limit [lindex $parameters 2]

	if {$group == "" || $limit == ""} {
		bncreply "Syntax: setlimit <Group> <Limit>"
		haltoutput
		return
	}

	set result [virtual:vsetlimit $group $limit]

	if {[lindex $result 0] == -1} {
		bncreply [lindex $result 1]
		haltoutput
		return
	}

	bncreply "$group is now limited to $limit users."
	haltoutput
}

proc virtual:vgroupusers {group} {
	set bncs [list]
	foreach u [bncuserlist] {
		if {[string equal -nocase $group [getbncuser $u tag group]]} {
			lappend bncs $u
		}
	}

	return $bncs
}

proc virtual:cmd:groups {client parameters} {
	set bncs [list]
	foreach u [bncuserlist] {
		if {[virtual:getgroup $u] != ""} {
			lappend bncs [virtual:getgroup $u]
		}
	}

	set groups [sbnc:uniq $bncs]

	bncreply "Groups:"

	foreach group $groups {
		set bncs [list]
		foreach u [bncuserlist] {
			if {[string equal -nocase $group [getbncuser $u tag group]]} {
				lappend bncs $u
			}
		}

		bncreply "$group [llength $bncs]/[virtual:getmaxbncs $group]"
	}

	bncreply "End of GROUPS."
	haltoutput
}

# iface commands
# +user:
# vgetgroup
# visadmin
# +vadmin:
# vgetlimit
# vgroupusers
# vadduser user pass
# vdeluser user
# vresetpass user pass
# vuptimehr [user]
# vchannels [user]
# vsuspended [user]
# vclient [user]
# +admin:
# vgetlimit [group]
# vsetlimit [group] [limit]
# vgetgroup [user]
# visadmin [user]
# vgroups
# vgroupusers [group]
# vadmin [user]
# vunadmin [user]
# vaddgroup [group] [limit]
# vdelgroup [group]
# vsetgroup user group

proc access:vadmin {user} {
	if {[access:admin $user]} { return 1}
	if {[virtual:getgroup $user] == ""} { return 0 }
	if {![virtual:isadmin $user]} { return 0 }

	return 1
}

proc virtual:canmodify {user} {
	if {[string equal -nocase [virtual:getgroup $user] [virtual:getgroup [getctx]]] || [getbncuser [getctx] admin]} {
		return 1
	} else {
		return -code error "You cannot modify this user."
	}
}

proc virtual:canmodifygroup {group} {
	if {[string equal -nocase $group [virtual:getgroup [getctx]]] || [getbncuser [getctx] admin]} {
		return 1
	} else {
		return -code error "You cannot modify this user."
	}
}

# Iface2 commands

proc iface-virtual:getgroup {username} {
	virtual:canmodify $username

	return [itype_string [virtual:getgroup $username]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgroup" "iface-virtual:getgroup"
}

proc iface-virtual:getmygroup {} {
	return [itype_string [virtual:getgroup [getctx]]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getmygroup" "iface-virtual:getmygroup"
}

proc iface-virtual:isvadmin {username} {
	virtual:canmodify $username

	return [itype_string [access:vadmin $username]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "isvadmin" "iface-virtual:isvadmin"
}

proc iface-virtual:getgrouplimit {group} {
	virtual:canmodifygroup $group

	return [itype_string [virtual:getmaxbncs $group]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgrouplimit" "iface-virtual:getgrouplimit" "access:vadmin"
}

proc iface-virtual:getgroupusers {group} {
	virtual:canmodifygroup $group

	return [itype_list_strings [virtual:vgroupusers $group]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgroupusers" "iface-virtual:getgroupusers" "access:vadmin"
}

proc iface-virtual:vadduser {username password} {
	if {[getbncuser [getctx] admin]} {
		set checklimits 0
	} else {
		set checklimits 1
	}

	virtual:vadduser $username $password [virtual:getgroup [getctx]] $checklimits

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vadduser" "iface-virtual:vadduser" "access:vadmin"
}

proc iface-virtual:vdeluser {username} {
	virtual:canmodify $username

	virtual:vdeluser [getctx] $username

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vdeluser" "iface-virtual:vdeluser" "access:vadmin"
}

proc iface-virtual:vresetpass {username password} {
	virtual:canmodify $username

	setbncuser $username password $password

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vresetpass" "iface-virtual:vresetpass" "access:vadmin"
}

proc iface-virtual:vgetuptimehr {username} {
	virtual:canmodify $username

	return [itype_string [duration [getbncuser $username uptime]]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vgetuptimehr" "iface-virtual:vgetuptimehr" "access:vadmin"
}

proc iface-virtual:vgetchannels {username} {
	virtual:canmodify $username

	setctx $username
	return [itype_list_strings [internalchannels]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vgetchannels" "iface-virtual:vgetchannels" "access:vadmin"
}

proc iface-virtual:vissuspended {username} {
	virtual:canmodify $username

	return [itype_string [getbncuser $username lock]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vissuspended" "iface-virtual:vissuspended" "access:vadmin"
}

proc iface-virtual:vgetclient {username} {
	virtual:canmodify $username

	setctx $username
	return [itype_string [getbncuser $username client]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vgetclient" "iface-virtual:vgetclient" "access:vadmin"
}

proc iface-virtual:setgrouplimit {group limit} {
	virtual:vsetlimit $group $limit

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "setgrouplimit" "iface-virtual:setgrouplimit" "access:admin"
}

proc iface-virtual:getgroups {} {
	set groups [list]

	foreach user [bncuserlist] {
		if {[virtual:getgroup $user] != ""} {
			lappend groups [string tolower [virtual:getgroup $user]]
		}
	}

	return [itype_list_strings [sbnc:uniq $groups]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgroups" "iface-virtual:getgroups" "access:admin"
}

proc iface-virtual:getgroup {username} {
	return [itype_string [virtual:getgroup $username]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgroup" "iface-virtual:getgroup" "access:admin"
}

proc iface-virtual:setgroup {username group} {
	virtual:setgroup $username $group

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "setgroup" "iface-virtual:setgroup" "access:admin"
}

proc iface-virtual:vadmin {username} {
	virtual:vadmin $username

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vadmin" "iface-virtual:vadmin" "access:admin"
}

proc iface-virtual:vunadmin {username} {
	virtual:vunadmin $username]

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "vunadmin" "iface-virtual:vunadmin" "access:admin"
}

proc iface-virtual:addgroup {group limit} {
	virtual:vaddgroup $group $limit

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "addgroup" "iface-virtual:addgroup" "access:admin"
}

proc iface-virtual:delgroup {group} {
	virtual:vdelgroup $group

	return ""
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "delgroup" "iface-virtual:delgroup" "access:admin"
}

proc iface-virtual:getgroupadmin {group} {
	return [itype_string [virtual:getadmin $group]]
}

if {[info commands "registerifacecmd"] != ""} {
	registerifacecmd "virtual" "getgroupadmin" "iface-virtual:getgroupadmin" "access:admin"
}
