2012-04-17 20:09:50 +00:00
/*
* Copyright ( c ) 2007 Jilles Tjoelker , et al .
* Rights to this code are as documented in doc / LICENSE .
*
* ChanServ ACCESS command
*
* $ Id $
*/
2012-10-04 05:01:29 +00:00
# include "atheme-compat.h"
2012-04-17 20:09:50 +00:00
# include "template.h"
DECLARE_MODULE_V1
(
" contrib/cs_access_alias " , FALSE , _modinit , _moddeinit ,
" $Id$ " ,
" freenode <http://www.freenode.net> "
) ;
static void cs_cmd_access ( sourceinfo_t * si , int parc , char * parv [ ] ) ;
command_t cs_access = { " ACCESS " , " Manipulates channel access lists. " ,
AC_NONE , 4 , cs_cmd_access , { . path = " contrib/access " } } ;
void _modinit ( module_t * m )
{
service_named_bind_command ( " chanserv " , & cs_access ) ;
}
void _moddeinit ( module_unload_intent_t intent )
{
service_named_unbind_command ( " chanserv " , & cs_access ) ;
}
static void compat_cmd ( sourceinfo_t * si , const char * cmdname , char * channel , char * arg1 , char * arg2 , char * arg3 )
{
int newparc ;
char * newparv [ 5 ] ;
command_t * cmd ;
newparv [ 0 ] = channel ;
newparv [ 1 ] = arg1 ;
newparv [ 2 ] = arg2 ;
newparv [ 3 ] = arg3 ;
newparv [ 4 ] = NULL ;
/* this assumes arg3!=NULL implies arg2!=NULL implies arg1!=NULL */
newparc = 1 + ( arg1 ! = NULL ) + ( arg2 ! = NULL ) + ( arg3 ! = NULL ) ;
cmd = command_find ( si - > service - > commands , cmdname ) ;
if ( cmd ! = NULL )
command_exec ( si - > service , si , cmd , newparc , newparv ) ;
else
command_fail ( si , fault_unimplemented , _ ( " Command \2 %s \2 not loaded? " ) , cmdname ) ;
}
typedef struct {
const char * res ;
unsigned int level ;
} template_iter_t ;
static int global_template_search ( const char * key , void * data , void * privdata )
{
template_iter_t * iter = privdata ;
default_template_t * def_t = data ;
if ( def_t - > flags = = iter - > level )
iter - > res = key ;
return 0 ;
}
static const char * get_template_name ( mychan_t * mc , unsigned int level )
{
metadata_t * md ;
const char * p , * q , * r ;
char * s ;
char ss [ 40 ] ;
static char flagname [ 400 ] ;
template_iter_t iter ;
md = metadata_find ( mc , " private:templates " ) ;
if ( md ! = NULL )
{
p = md - > value ;
while ( p ! = NULL )
{
while ( * p = = ' ' )
p + + ;
q = strchr ( p , ' = ' ) ;
if ( q = = NULL )
break ;
r = strchr ( q , ' ' ) ;
if ( r ! = NULL & & r < q )
break ;
mowgli_strlcpy ( ss , q , sizeof ss ) ;
if ( r ! = NULL & & r - q < ( int ) ( sizeof ss - 1 ) )
{
ss [ r - q ] = ' \0 ' ;
}
if ( level = = flags_to_bitmask ( ss , 0 ) )
{
mowgli_strlcpy ( flagname , p , sizeof flagname ) ;
s = strchr ( flagname , ' = ' ) ;
if ( s ! = NULL )
* s = ' \0 ' ;
return flagname ;
}
p = r ;
}
}
iter . res = NULL ;
iter . level = level ;
mowgli_patricia_foreach ( global_template_dict , global_template_search , & iter ) ;
return iter . res ;
}
static void access_list ( sourceinfo_t * si , mychan_t * mc , int parc , char * parv [ ] )
{
mowgli_node_t * n ;
chanacs_t * ca ;
const char * str1 , * str2 ;
int i = 1 ;
bool operoverride = false ;
/* Copied from modules/chanserv/flags.c */
/* Note: This overrides the normal need of +A access unless private */
if ( use_channel_private & & mc - > flags & MC_PRIVATE & &
! chanacs_source_has_flag ( mc , si , CA_ACLVIEW ) )
{
if ( has_priv ( si , PRIV_CHAN_AUSPEX ) )
operoverride = true ;
else
{
command_fail ( si , fault_noprivs , _ ( " You are not authorized to perform this operation. " ) ) ;
return ;
}
}
command_success_nodata ( si , _ ( " Entry Nickname/Host Flags " ) ) ;
command_success_nodata ( si , " ----- ---------------------- ----- " ) ;
MOWGLI_ITER_FOREACH ( n , mc - > chanacs . head )
{
ca = n - > data ;
/* Change: don't show akicks */
if ( ca - > level = = CA_AKICK )
continue ;
str1 = get_template_name ( mc , ca - > level ) ;
str2 = ca - > tmodified ? time_ago ( ca - > tmodified ) : " ? " ;
if ( str1 ! = NULL )
command_success_nodata ( si , _ ( " %-5d %-22s %s (%s) [modified %s ago] " ) , i , ca - > entity ? ca - > entity - > name : ca - > host , bitmask_to_flags ( ca - > level ) , str1 ,
str2 ) ;
else
command_success_nodata ( si , _ ( " %-5d %-22s %s [modified %s ago] " ) , i , ca - > entity ? ca - > entity - > name : ca - > host , bitmask_to_flags ( ca - > level ) ,
str2 ) ;
i + + ;
}
command_success_nodata ( si , " ----- ---------------------- ----- " ) ;
command_success_nodata ( si , _ ( " End of \2 %s \2 FLAGS listing. " ) , mc - > name ) ;
if ( operoverride )
logcommand ( si , CMDLOG_ADMIN , " %s ACCESS LIST (oper override) " , mc - > name ) ;
else
logcommand ( si , CMDLOG_GET , " %s ACCESS LIST " , mc - > name ) ;
}
static void cs_cmd_access ( sourceinfo_t * si , int parc , char * parv [ ] )
{
char * chan , * cmd ;
mychan_t * mc ;
char killit [ ] = " -* " ;
char deftemplate [ ] = " OP " ;
char defaccess [ ] = " =votirA " ;
if ( parc < 2 )
{
command_fail ( si , fault_needmoreparams , STR_INSUFFICIENT_PARAMS , " ACCESS " ) ;
command_fail ( si , fault_needmoreparams , _ ( " Syntax: ACCESS <#channel> ADD|DEL|LIST [nick] [level] " ) ) ;
return ;
}
if ( parv [ 0 ] [ 0 ] = = ' # ' )
chan = parv [ 0 ] , cmd = parv [ 1 ] ;
else if ( parv [ 1 ] [ 0 ] = = ' # ' )
cmd = parv [ 0 ] , chan = parv [ 1 ] ;
else
{
command_fail ( si , fault_badparams , STR_INVALID_PARAMS , " ACCESS " ) ;
command_fail ( si , fault_badparams , _ ( " Syntax: ACCESS <#channel> ADD|DEL|LIST [nick] [level] " ) ) ;
return ;
}
mc = mychan_find ( chan ) ;
if ( mc = = NULL )
{
command_fail ( si , fault_nosuch_target , _ ( " \2 %s \2 is not registered. " ) , chan ) ;
return ;
}
if ( ! strcasecmp ( cmd , " LIST " ) )
access_list ( si , mc , parc - 2 , parv + 2 ) ;
else if ( parc < 3 )
{
command_fail ( si , fault_needmoreparams , STR_INSUFFICIENT_PARAMS , " ACCESS " ) ;
command_fail ( si , fault_needmoreparams , _ ( " Syntax: ACCESS <#channel> ADD|DEL <nick> [level] " ) ) ;
return ;
}
else if ( ! strcasecmp ( cmd , " ADD " ) )
compat_cmd ( si , " FLAGS " , chan , parv [ 2 ] , parc > 3 ? parv [ 3 ] : ( get_template_flags ( mc , deftemplate ) ? deftemplate : defaccess ) , NULL ) ;
else if ( ! strcasecmp ( cmd , " DEL " ) )
compat_cmd ( si , " FLAGS " , chan , parv [ 2 ] , killit , NULL ) ;
else
command_fail ( si , fault_badparams , _ ( " Invalid command. Use \2 /%s%s help \2 for a command listing. " ) , ( ircd - > uses_rcommand = = FALSE ) ? " msg " : " " , si - > service - > disp ) ;
}