2004-05-04 16:09:35 +00:00
/*
* Asterisk - - A telephony toolkit for Linux .
*
* Group Manipulation Applications
*
* Copyright ( c ) 2004 Digium
*
* Mark Spencer < markster @ digium . com >
*
* This program is free software , distributed under the terms of
* the GNU General Public License
*/
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
2004-10-03 16:34:52 +00:00
# include <sys/types.h>
# include <regex.h>
2004-05-04 16:09:35 +00:00
# include <asterisk/file.h>
# include <asterisk/logger.h>
# include <asterisk/options.h>
# include <asterisk/channel.h>
# include <asterisk/pbx.h>
# include <asterisk/module.h>
2004-05-09 07:51:44 +00:00
# include <asterisk/utils.h>
2004-10-03 16:34:52 +00:00
# include <asterisk/cli.h>
# include <asterisk/app.h>
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
STANDARD_LOCAL_USER ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
LOCAL_USER_DECL ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
static int group_count_exec ( struct ast_channel * chan , void * data )
{
int res = 0 ;
int count ;
struct localuser * u ;
char group [ 80 ] = " " ;
char category [ 80 ] = " " ;
char ret [ 80 ] = " " ;
char * grp ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
LOCAL_USER_ADD ( u ) ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
ast_app_group_split_group ( data , group , sizeof ( group ) , category , sizeof ( category ) ) ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
if ( ast_strlen_zero ( group ) ) {
grp = pbx_builtin_getvar_helper ( chan , category ) ;
strncpy ( group , grp , sizeof ( group ) - 1 ) ;
}
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
count = ast_app_group_get_count ( group , category ) ;
snprintf ( ret , sizeof ( ret ) , " %d " , count ) ;
pbx_builtin_setvar_helper ( chan , " GROUPCOUNT " , ret ) ;
2004-05-04 16:09:35 +00:00
2004-10-03 16:34:52 +00:00
LOCAL_USER_REMOVE ( u ) ;
2004-07-16 04:32:17 +00:00
2004-10-03 16:34:52 +00:00
return res ;
2004-05-04 16:09:35 +00:00
}
2004-10-03 16:34:52 +00:00
static int group_match_count_exec ( struct ast_channel * chan , void * data )
2004-05-04 16:09:35 +00:00
{
2004-10-03 16:34:52 +00:00
int res = 0 ;
2004-05-04 16:09:35 +00:00
int count ;
struct localuser * u ;
2004-10-03 16:34:52 +00:00
char group [ 80 ] = " " ;
char category [ 80 ] = " " ;
char ret [ 80 ] = " " ;
2004-05-04 16:09:35 +00:00
LOCAL_USER_ADD ( u ) ;
2004-10-03 16:34:52 +00:00
ast_app_group_split_group ( data , group , sizeof ( group ) , category , sizeof ( category ) ) ;
2004-07-16 04:32:17 +00:00
2004-10-03 16:34:52 +00:00
if ( ! ast_strlen_zero ( group ) ) {
count = ast_app_group_match_get_count ( group , category ) ;
snprintf ( ret , sizeof ( ret ) , " %d " , count ) ;
pbx_builtin_setvar_helper ( chan , " GROUPCOUNT " , ret ) ;
2004-05-04 16:09:35 +00:00
}
2004-10-03 16:34:52 +00:00
2004-05-04 16:09:35 +00:00
LOCAL_USER_REMOVE ( u ) ;
2004-10-03 16:34:52 +00:00
2004-05-04 16:09:35 +00:00
return res ;
}
static int group_set_exec ( struct ast_channel * chan , void * data )
{
2004-10-03 16:34:52 +00:00
int res = 0 ;
2004-05-04 16:09:35 +00:00
struct localuser * u ;
LOCAL_USER_ADD ( u ) ;
2004-07-16 04:32:17 +00:00
2004-10-03 16:34:52 +00:00
if ( ast_app_group_set_channel ( chan , data ) )
2004-07-16 04:32:17 +00:00
ast_log ( LOG_WARNING , " SetGroup requires an argument (group name) \n " ) ;
2004-05-04 16:09:35 +00:00
LOCAL_USER_REMOVE ( u ) ;
return res ;
}
static int group_check_exec ( struct ast_channel * chan , void * data )
{
2004-10-03 16:34:52 +00:00
int res = 0 ;
2004-05-04 16:09:35 +00:00
int max , count ;
struct localuser * u ;
2004-10-03 16:34:52 +00:00
char limit [ 80 ] = " " ;
char category [ 80 ] = " " ;
2004-05-04 16:09:35 +00:00
LOCAL_USER_ADD ( u ) ;
2004-10-03 16:34:52 +00:00
if ( ! data | | ast_strlen_zero ( data ) ) {
ast_log ( LOG_WARNING , " CheckGroup requires an argument(max[@category]) \n " ) ;
return res ;
}
ast_app_group_split_group ( data , limit , sizeof ( limit ) , category , sizeof ( category ) ) ;
if ( ( sscanf ( limit , " %i " , & max ) = = 1 ) & & ( max > - 1 ) ) {
count = ast_app_group_get_count ( pbx_builtin_getvar_helper ( chan , category ) , category ) ;
if ( count > max ) {
if ( ast_exists_extension ( chan , chan - > context , chan - > exten , chan - > priority + 101 , chan - > cid . cid_num ) )
chan - > priority + = 100 ;
2004-07-16 04:32:17 +00:00
else
2004-10-03 16:34:52 +00:00
res = - 1 ;
}
2004-05-04 16:09:35 +00:00
} else
2004-10-03 16:34:52 +00:00
ast_log ( LOG_WARNING , " CheckGroup requires a positive integer argument (max) \n " ) ;
2004-05-04 16:09:35 +00:00
LOCAL_USER_REMOVE ( u ) ;
return res ;
}
2004-10-03 16:34:52 +00:00
static int group_show_channels ( int fd , int argc , char * argv [ ] )
{
# define FORMAT_STRING "%-25s %-20s %-20s\n"
struct ast_channel * c = NULL ;
int numchans = 0 ;
struct ast_var_t * current ;
struct varshead * headp ;
regex_t regexbuf ;
int havepattern = 0 ;
if ( argc < 3 | | argc > 4 )
return RESULT_SHOWUSAGE ;
if ( argc = = 4 ) {
if ( regcomp ( & regexbuf , argv [ 3 ] , REG_EXTENDED | REG_NOSUB ) )
return RESULT_SHOWUSAGE ;
havepattern = 1 ;
}
c = ast_channel_walk_locked ( NULL ) ;
ast_cli ( fd , FORMAT_STRING , " Channel " , " Group " , " Category " ) ;
while ( c ) {
headp = & c - > varshead ;
AST_LIST_TRAVERSE ( headp , current , entries ) {
if ( ! strncmp ( ast_var_name ( current ) , GROUP_CATEGORY_PREFIX " _ " , strlen ( GROUP_CATEGORY_PREFIX ) + 1 ) ) {
if ( ! havepattern | | ! regexec ( & regexbuf , ast_var_value ( current ) , 0 , NULL , 0 ) ) {
ast_cli ( fd , FORMAT_STRING , c - > name , ast_var_value ( current ) ,
( ast_var_name ( current ) + strlen ( GROUP_CATEGORY_PREFIX ) + 1 ) ) ;
numchans + + ;
}
} else if ( ! strcmp ( ast_var_name ( current ) , GROUP_CATEGORY_PREFIX ) ) {
if ( ! havepattern | | ! regexec ( & regexbuf , ast_var_value ( current ) , 0 , NULL , 0 ) ) {
ast_cli ( fd , FORMAT_STRING , c - > name , ast_var_value ( current ) , " (default) " ) ;
numchans + + ;
}
}
}
numchans + + ;
ast_mutex_unlock ( & c - > lock ) ;
c = ast_channel_walk_locked ( c ) ;
}
if ( havepattern )
regfree ( & regexbuf ) ;
ast_cli ( fd , " %d active channel(s) \n " , numchans ) ;
return RESULT_SUCCESS ;
}
static char * tdesc = " Group Management Routines " ;
static char * app_group_count = " GetGroupCount " ;
static char * app_group_set = " SetGroup " ;
static char * app_group_check = " CheckGroup " ;
static char * app_group_match_count = " GetGroupMatchCount " ;
static char * group_count_synopsis = " GetGroupCount([groupname][@category]) " ;
static char * group_set_synopsis = " SetGroup(groupname[@category]) " ;
static char * group_check_synopsis = " CheckGroup(max[@category]) " ;
static char * group_match_count_synopsis = " GetGroupMatchCount(groupmatch[@category]) " ;
static char * group_count_descrip =
" GetGroupCount([group][@category]) \n "
" Calculates the group count for the specified group, or uses \n "
" the current channel's group if not specifed (and non-empty). \n "
" Stores result in GROUPCOUNT. Always returns 0. \n " ;
static char * group_set_descrip =
" SetGroup(group) \n "
" Sets the channel group to the specified value. Equivalent to \n "
" SetVar(GROUP=group). Always returns 0. \n " ;
static char * group_check_descrip =
" CheckGroup(max[@category]) \n "
" Checks that the current number of total channels in the \n "
" current channel's group does not exceed 'max'. If the number \n "
" does not exceed 'max', we continue to the next step. If the \n "
" number does in fact exceed max, if priority n+101 exists, then \n "
" execution continues at that step, otherwise -1 is returned. \n " ;
static char * group_match_count_descrip =
" GetGroupMatchCount(groupmatch[@category]) \n "
" Calculates the group count for all groups that match the specified \n "
" pattern. Uses standard regular expression matching (see regex(7)). \n "
" Stores result in GROUPCOUNT. Always returns 0. \n " ;
static char show_channels_usage [ ] =
" Usage: group show channels [pattern] \n "
" Lists all currently active channels with channel group(s) specified. \n Optional regular expression pattern is matched to group names for each channel. \n " ;
static struct ast_cli_entry cli_show_channels =
{ { " group " , " show " , " channels " , NULL } , group_show_channels , " Show active channels with group(s) " , show_channels_usage } ;
2004-05-04 16:09:35 +00:00
int unload_module ( void )
{
int res ;
STANDARD_HANGUP_LOCALUSERS ;
2004-10-03 16:34:52 +00:00
ast_cli_unregister ( & cli_show_channels ) ;
2004-05-04 16:09:35 +00:00
res = ast_unregister_application ( app_group_count ) ;
res | = ast_unregister_application ( app_group_set ) ;
res | = ast_unregister_application ( app_group_check ) ;
2004-10-03 16:34:52 +00:00
res | = ast_unregister_application ( app_group_match_count ) ;
2004-05-04 16:09:35 +00:00
return res ;
}
int load_module ( void )
{
int res ;
res = ast_register_application ( app_group_count , group_count_exec , group_count_synopsis , group_count_descrip ) ;
res | = ast_register_application ( app_group_set , group_set_exec , group_set_synopsis , group_set_descrip ) ;
res | = ast_register_application ( app_group_check , group_check_exec , group_check_synopsis , group_check_descrip ) ;
2004-10-03 16:34:52 +00:00
res | = ast_register_application ( app_group_match_count , group_match_count_exec , group_match_count_synopsis , group_match_count_descrip ) ;
ast_cli_register ( & cli_show_channels ) ;
2004-05-04 16:09:35 +00:00
return res ;
}
char * description ( void )
{
return tdesc ;
}
int usecount ( void )
{
int res ;
STANDARD_USECOUNT ( res ) ;
return res ;
}
char * key ( )
{
return ASTERISK_GPL_KEY ;
}