00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <sys/types.h>
00031 #include <regex.h>
00032
00033 #include "asterisk.h"
00034
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 16344 $")
00036
00037 #include "asterisk/file.h"
00038 #include "asterisk/logger.h"
00039 #include "asterisk/options.h"
00040 #include "asterisk/channel.h"
00041 #include "asterisk/pbx.h"
00042 #include "asterisk/module.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/cli.h"
00045 #include "asterisk/app.h"
00046
00047 STANDARD_LOCAL_USER;
00048
00049 LOCAL_USER_DECL;
00050
00051 static int group_count_exec(struct ast_channel *chan, void *data)
00052 {
00053 int res = 0;
00054 int count;
00055 struct localuser *u;
00056 char group[80] = "";
00057 char category[80] = "";
00058 char ret[80] = "";
00059 char *grp;
00060 static int deprecation_warning = 0;
00061
00062 LOCAL_USER_ADD(u);
00063
00064 if (!deprecation_warning) {
00065 ast_log(LOG_WARNING, "The GetGroupCount application has been deprecated, please use the GROUP_COUNT function.\n");
00066 deprecation_warning = 1;
00067 }
00068
00069 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
00070
00071 if (ast_strlen_zero(group)) {
00072 grp = pbx_builtin_getvar_helper(chan, category);
00073 strncpy(group, grp, sizeof(group) - 1);
00074 }
00075
00076 count = ast_app_group_get_count(group, category);
00077 snprintf(ret, sizeof(ret), "%d", count);
00078 pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
00079
00080 LOCAL_USER_REMOVE(u);
00081
00082 return res;
00083 }
00084
00085 static int group_match_count_exec(struct ast_channel *chan, void *data)
00086 {
00087 int res = 0;
00088 int count;
00089 struct localuser *u;
00090 char group[80] = "";
00091 char category[80] = "";
00092 char ret[80] = "";
00093 static int deprecation_warning = 0;
00094
00095 LOCAL_USER_ADD(u);
00096
00097 if (!deprecation_warning) {
00098 ast_log(LOG_WARNING, "The GetGroupMatchCount application has been deprecated, please use the GROUP_MATCH_COUNT function.\n");
00099 deprecation_warning = 1;
00100 }
00101
00102 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
00103
00104 if (!ast_strlen_zero(group)) {
00105 count = ast_app_group_match_get_count(group, category);
00106 snprintf(ret, sizeof(ret), "%d", count);
00107 pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
00108 }
00109
00110 LOCAL_USER_REMOVE(u);
00111
00112 return res;
00113 }
00114
00115 static int group_set_exec(struct ast_channel *chan, void *data)
00116 {
00117 int res = 0;
00118 struct localuser *u;
00119 static int deprecation_warning = 0;
00120
00121 LOCAL_USER_ADD(u);
00122
00123 if (!deprecation_warning) {
00124 ast_log(LOG_WARNING, "The SetGroup application has been deprecated, please use the GROUP() function.\n");
00125 deprecation_warning = 1;
00126 }
00127
00128 if (ast_app_group_set_channel(chan, data))
00129 ast_log(LOG_WARNING, "SetGroup requires an argument (group name)\n");
00130
00131 LOCAL_USER_REMOVE(u);
00132 return res;
00133 }
00134
00135 static int group_check_exec(struct ast_channel *chan, void *data)
00136 {
00137 int res = 0;
00138 int max, count;
00139 struct localuser *u;
00140 char limit[80]="";
00141 char category[80]="";
00142 static int deprecation_warning = 0;
00143 char *parse;
00144 int priority_jump = 0;
00145 AST_DECLARE_APP_ARGS(args,
00146 AST_APP_ARG(max);
00147 AST_APP_ARG(options);
00148 );
00149
00150 LOCAL_USER_ADD(u);
00151
00152 if (!deprecation_warning) {
00153 ast_log(LOG_WARNING, "The CheckGroup application has been deprecated, please use a combination of the GotoIf application and the GROUP_COUNT() function.\n");
00154 deprecation_warning = 1;
00155 }
00156
00157 if (!(parse = ast_strdupa(data))) {
00158 ast_log(LOG_WARNING, "Memory Error!\n");
00159 LOCAL_USER_REMOVE(u);
00160 return -1;
00161 }
00162
00163 AST_STANDARD_APP_ARGS(args, parse);
00164
00165 if (args.options) {
00166 if (strchr(args.options, 'j'))
00167 priority_jump = 1;
00168 }
00169
00170 if (ast_strlen_zero(args.max)) {
00171 ast_log(LOG_WARNING, "CheckGroup requires an argument(max[@category][|options])\n");
00172 return res;
00173 }
00174
00175 ast_app_group_split_group(args.max, limit, sizeof(limit), category, sizeof(category));
00176
00177 if ((sscanf(limit, "%d", &max) == 1) && (max > -1)) {
00178 count = ast_app_group_get_count(pbx_builtin_getvar_helper(chan, category), category);
00179 if (count > max) {
00180 pbx_builtin_setvar_helper(chan, "CHECKGROUPSTATUS", "OVERMAX");
00181 if (priority_jump || option_priority_jumping) {
00182 if (!ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101))
00183 res = -1;
00184 }
00185 } else
00186 pbx_builtin_setvar_helper(chan, "CHECKGROUPSTATUS", "OK");
00187 } else
00188 ast_log(LOG_WARNING, "CheckGroup requires a positive integer argument (max)\n");
00189
00190 LOCAL_USER_REMOVE(u);
00191 return res;
00192 }
00193
00194 static int group_show_channels(int fd, int argc, char *argv[])
00195 {
00196 #define FORMAT_STRING "%-25s %-20s %-20s\n"
00197
00198 struct ast_channel *c = NULL;
00199 int numchans = 0;
00200 struct ast_var_t *current;
00201 struct varshead *headp;
00202 regex_t regexbuf;
00203 int havepattern = 0;
00204
00205 if (argc < 3 || argc > 4)
00206 return RESULT_SHOWUSAGE;
00207
00208 if (argc == 4) {
00209 if (regcomp(®exbuf, argv[3], REG_EXTENDED | REG_NOSUB))
00210 return RESULT_SHOWUSAGE;
00211 havepattern = 1;
00212 }
00213
00214 ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category");
00215 while ( (c = ast_channel_walk_locked(c)) != NULL) {
00216 headp=&c->varshead;
00217 AST_LIST_TRAVERSE(headp,current,entries) {
00218 if (!strncmp(ast_var_name(current), GROUP_CATEGORY_PREFIX "_", strlen(GROUP_CATEGORY_PREFIX) + 1)) {
00219 if (!havepattern || !regexec(®exbuf, ast_var_value(current), 0, NULL, 0)) {
00220 ast_cli(fd, FORMAT_STRING, c->name, ast_var_value(current),
00221 (ast_var_name(current) + strlen(GROUP_CATEGORY_PREFIX) + 1));
00222 numchans++;
00223 }
00224 } else if (!strcmp(ast_var_name(current), GROUP_CATEGORY_PREFIX)) {
00225 if (!havepattern || !regexec(®exbuf, ast_var_value(current), 0, NULL, 0)) {
00226 ast_cli(fd, FORMAT_STRING, c->name, ast_var_value(current), "(default)");
00227 numchans++;
00228 }
00229 }
00230 }
00231 numchans++;
00232 ast_mutex_unlock(&c->lock);
00233 }
00234
00235 if (havepattern)
00236 regfree(®exbuf);
00237
00238 ast_cli(fd, "%d active channel%s\n", numchans, (numchans != 1) ? "s" : "");
00239 return RESULT_SUCCESS;
00240 #undef FORMAT_STRING
00241 }
00242
00243 static char *tdesc = "Group Management Routines";
00244
00245 static char *app_group_count = "GetGroupCount";
00246 static char *app_group_set = "SetGroup";
00247 static char *app_group_check = "CheckGroup";
00248 static char *app_group_match_count = "GetGroupMatchCount";
00249
00250 static char *group_count_synopsis = "Get the channel count of a group";
00251 static char *group_set_synopsis = "Set the channel's group";
00252 static char *group_check_synopsis = "Check the channel count of a group against a limit";
00253 static char *group_match_count_synopsis = "Get the channel count of all groups that match a pattern";
00254
00255 static char *group_count_descrip =
00256 "Usage: GetGroupCount([groupname][@category])\n"
00257 " Calculates the group count for the specified group, or uses\n"
00258 "the current channel's group if not specifed (and non-empty).\n"
00259 "Stores result in GROUPCOUNT. \n"
00260 "Note: This application has been deprecated, please use the function\n"
00261 "GROUP_COUNT.\n";
00262
00263 static char *group_set_descrip =
00264 "Usage: SetGroup(groupname[@category])\n"
00265 " Sets the channel group to the specified value. Equivalent to\n"
00266 "Set(GROUP=group). Always returns 0.\n";
00267
00268 static char *group_check_descrip =
00269 "Usage: CheckGroup(max[@category][|options])\n"
00270 " Checks that the current number of total channels in the\n"
00271 "current channel's group does not exceed 'max'. If the number\n"
00272 "does not exceed 'max', we continue to the next step. \n"
00273 " The option string may contain zero of the following character:\n"
00274 " 'j' -- jump to n+101 priority if the number does in fact exceed max,\n"
00275 " and priority n+101 exists. Execuation then continues at that\n"
00276 " step, otherwise -1 is returned.\n"
00277 " This application sets the following channel variable upon successful completion:\n"
00278 " CHECKGROUPSTATUS The status of the check that the current channel's\n"
00279 " group does not exceed 'max'. It's value is one of\n"
00280 " OK | OVERMAX \n";
00281
00282 static char *group_match_count_descrip =
00283 "Usage: GetGroupMatchCount(groupmatch[@category])\n"
00284 " Calculates the group count for all groups that match the specified\n"
00285 "pattern. Uses standard regular expression matching (see regex(7)).\n"
00286 "Stores result in GROUPCOUNT. Always returns 0.\n"
00287 "Note: This application has been deprecated, please use the function\n"
00288 "GROUP_MATCH_COUNT.\n";
00289
00290 static char show_channels_usage[] =
00291 "Usage: group show channels [pattern]\n"
00292 " Lists all currently active channels with channel group(s) specified.\n Optional regular expression pattern is matched to group names for each channel.\n";
00293
00294 static struct ast_cli_entry cli_show_channels =
00295 { { "group", "show", "channels", NULL }, group_show_channels, "Show active channels with group(s)", show_channels_usage};
00296
00297 int unload_module(void)
00298 {
00299 int res;
00300
00301 res = ast_cli_unregister(&cli_show_channels);
00302 res |= ast_unregister_application(app_group_count);
00303 res |= ast_unregister_application(app_group_set);
00304 res |= ast_unregister_application(app_group_check);
00305 res |= ast_unregister_application(app_group_match_count);
00306
00307 STANDARD_HANGUP_LOCALUSERS;
00308
00309 return res;
00310 }
00311
00312 int load_module(void)
00313 {
00314 int res;
00315
00316 res = ast_register_application(app_group_count, group_count_exec, group_count_synopsis, group_count_descrip);
00317 res |= ast_register_application(app_group_set, group_set_exec, group_set_synopsis, group_set_descrip);
00318 res |= ast_register_application(app_group_check, group_check_exec, group_check_synopsis, group_check_descrip);
00319 res |= ast_register_application(app_group_match_count, group_match_count_exec, group_match_count_synopsis, group_match_count_descrip);
00320 res |= ast_cli_register(&cli_show_channels);
00321
00322 return res;
00323 }
00324
00325 char *description(void)
00326 {
00327 return tdesc;
00328 }
00329
00330 int usecount(void)
00331 {
00332 int res;
00333 STANDARD_USECOUNT(res);
00334 return res;
00335 }
00336
00337 char *key()
00338 {
00339 return ASTERISK_GPL_KEY;
00340 }