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