2 * Asterisk -- A telephony toolkit for Linux.
4 * Group Manipulation Applications
6 * Copyright (c) 2004 - 2005, Digium Inc.
8 * Mark Spencer <markster@digium.com>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
18 #include <sys/types.h>
21 #include "asterisk/file.h"
22 #include "asterisk/logger.h"
23 #include "asterisk/options.h"
24 #include "asterisk/channel.h"
25 #include "asterisk/pbx.h"
26 #include "asterisk/module.h"
27 #include "asterisk/utils.h"
28 #include "asterisk/cli.h"
29 #include "asterisk/app.h"
35 static int deprecation_warning = 0;
37 static char *group_count_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
42 char category[80] = "";
47 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
49 if (ast_strlen_zero(group)) {
50 grp = pbx_builtin_getvar_helper(chan, category);
51 strncpy(group, grp, sizeof(group) - 1);
54 count = ast_app_group_get_count(group, category);
55 snprintf(buf, len, "%d", count);
62 static struct ast_custom_function_obj group_count_function_obj = {
63 .name = "GROUP_COUNT",
64 .desc = "Calculates the group count for the specified group, or uses the current channel's group if not specifed (and non-empty).",
65 .syntax = "GROUP_COUNT([groupname][@category])",
66 .read = group_count_function_read,
70 static char *group_match_count_function_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
75 char category[80] = "";
79 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
81 if (!ast_strlen_zero(group)) {
82 count = ast_app_group_match_get_count(group, category);
83 snprintf(buf, len, "%d", count);
91 static struct ast_custom_function_obj group_match_count_function_obj = {
92 .name = "GROUP_MATCH_COUNT",
93 .desc = "Calculates the group count for all groups that match the specified pattern. Uses standard regular expression matching (see regex(7)).",
94 .syntax = "GROUP_MATCH_COUNT(groupmatch[@category])",
95 .read = group_match_count_function_read,
99 static int group_count_exec(struct ast_channel *chan, void *data)
105 char category[80] = "";
111 if (!deprecation_warning) {
112 ast_log(LOG_WARNING, "The GetGroupCount and GetGroupMatchCount applications have been deprecated, please use the GROUP_COUNT and GROUP_MATCH_COUNT functions.\n");
113 deprecation_warning = 1;
116 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
118 if (ast_strlen_zero(group)) {
119 grp = pbx_builtin_getvar_helper(chan, category);
120 strncpy(group, grp, sizeof(group) - 1);
123 count = ast_app_group_get_count(group, category);
124 snprintf(ret, sizeof(ret), "%d", count);
125 pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
127 LOCAL_USER_REMOVE(u);
132 static int group_match_count_exec(struct ast_channel *chan, void *data)
138 char category[80] = "";
143 if (!deprecation_warning) {
144 ast_log(LOG_WARNING, "The GetGroupCount and GetGroupMatchCount applications have been deprecated, please use the GROUP_COUNT and GROUP_MATCH_COUNT functions.\n");
145 deprecation_warning = 1;
148 ast_app_group_split_group(data, group, sizeof(group), category, sizeof(category));
150 if (!ast_strlen_zero(group)) {
151 count = ast_app_group_match_get_count(group, category);
152 snprintf(ret, sizeof(ret), "%d", count);
153 pbx_builtin_setvar_helper(chan, "GROUPCOUNT", ret);
156 LOCAL_USER_REMOVE(u);
161 static int group_set_exec(struct ast_channel *chan, void *data)
168 if (ast_app_group_set_channel(chan, data))
169 ast_log(LOG_WARNING, "SetGroup requires an argument (group name)\n");
171 LOCAL_USER_REMOVE(u);
175 static int group_check_exec(struct ast_channel *chan, void *data)
181 char category[80]="";
185 if (!data || ast_strlen_zero(data)) {
186 ast_log(LOG_WARNING, "CheckGroup requires an argument(max[@category])\n");
190 ast_app_group_split_group(data, limit, sizeof(limit), category, sizeof(category));
192 if ((sscanf(limit, "%d", &max) == 1) && (max > -1)) {
193 count = ast_app_group_get_count(pbx_builtin_getvar_helper(chan, category), category);
195 if (ast_exists_extension(chan, chan->context, chan->exten, chan->priority + 101, chan->cid.cid_num))
196 chan->priority += 100;
201 ast_log(LOG_WARNING, "CheckGroup requires a positive integer argument (max)\n");
203 LOCAL_USER_REMOVE(u);
207 static int group_show_channels(int fd, int argc, char *argv[])
209 #define FORMAT_STRING "%-25s %-20s %-20s\n"
211 struct ast_channel *c = NULL;
213 struct ast_var_t *current;
214 struct varshead *headp;
218 if (argc < 3 || argc > 4)
219 return RESULT_SHOWUSAGE;
222 if (regcomp(®exbuf, argv[3], REG_EXTENDED | REG_NOSUB))
223 return RESULT_SHOWUSAGE;
227 c = ast_channel_walk_locked(NULL);
228 ast_cli(fd, FORMAT_STRING, "Channel", "Group", "Category");
231 AST_LIST_TRAVERSE(headp,current,entries) {
232 if (!strncmp(ast_var_name(current), GROUP_CATEGORY_PREFIX "_", strlen(GROUP_CATEGORY_PREFIX) + 1)) {
233 if (!havepattern || !regexec(®exbuf, ast_var_value(current), 0, NULL, 0)) {
234 ast_cli(fd, FORMAT_STRING, c->name, ast_var_value(current),
235 (ast_var_name(current) + strlen(GROUP_CATEGORY_PREFIX) + 1));
238 } else if (!strcmp(ast_var_name(current), GROUP_CATEGORY_PREFIX)) {
239 if (!havepattern || !regexec(®exbuf, ast_var_value(current), 0, NULL, 0)) {
240 ast_cli(fd, FORMAT_STRING, c->name, ast_var_value(current), "(default)");
246 ast_mutex_unlock(&c->lock);
247 c = ast_channel_walk_locked(c);
253 ast_cli(fd, "%d active channel(s)\n", numchans);
254 return RESULT_SUCCESS;
257 static char *tdesc = "Group Management Routines";
259 static char *app_group_count = "GetGroupCount";
260 static char *app_group_set = "SetGroup";
261 static char *app_group_check = "CheckGroup";
262 static char *app_group_match_count = "GetGroupMatchCount";
264 static char *group_count_synopsis = "Get the channel count of a group";
265 static char *group_set_synopsis = "Set the channel's group";
266 static char *group_check_synopsis = "Check the channel count of a group against a limit";
267 static char *group_match_count_synopsis = "Get the channel count of all groups that match a pattern";
269 static char *group_count_descrip =
270 "Usage: GetGroupCount([groupname][@category])\n"
271 " Calculates the group count for the specified group, or uses\n"
272 "the current channel's group if not specifed (and non-empty).\n"
273 "Stores result in GROUPCOUNT. Always returns 0.\n"
274 "This application has been deprecated, please use the function\n"
277 static char *group_set_descrip =
278 "Usage: SetGroup(groupname[@category])\n"
279 " Sets the channel group to the specified value. Equivalent to\n"
280 "SetVar(GROUP=group). Always returns 0.\n";
282 static char *group_check_descrip =
283 "Usage: CheckGroup(max[@category])\n"
284 " Checks that the current number of total channels in the\n"
285 "current channel's group does not exceed 'max'. If the number\n"
286 "does not exceed 'max', we continue to the next step. If the\n"
287 "number does in fact exceed max, if priority n+101 exists, then\n"
288 "execution continues at that step, otherwise -1 is returned.\n";
290 static char *group_match_count_descrip =
291 "Usage: GetGroupMatchCount(groupmatch[@category])\n"
292 " Calculates the group count for all groups that match the specified\n"
293 "pattern. Uses standard regular expression matching (see regex(7)).\n"
294 "Stores result in GROUPCOUNT. Always returns 0.\n"
295 "This application has been deprecated, please use the function\n"
296 "GroupMatchCount.\n";
298 static char show_channels_usage[] =
299 "Usage: group show channels [pattern]\n"
300 " Lists all currently active channels with channel group(s) specified.\n Optional regular expression pattern is matched to group names for each channel.\n";
302 static struct ast_cli_entry cli_show_channels =
303 { { "group", "show", "channels", NULL }, group_show_channels, "Show active channels with group(s)", show_channels_usage};
305 int unload_module(void)
308 STANDARD_HANGUP_LOCALUSERS;
309 ast_cli_unregister(&cli_show_channels);
310 res = ast_unregister_application(app_group_count);
311 res |= ast_unregister_application(app_group_set);
312 res |= ast_unregister_application(app_group_check);
313 res |= ast_unregister_application(app_group_match_count);
314 res |= ast_custom_function_unregister(&group_count_function_obj);
315 res |= ast_custom_function_unregister(&group_match_count_function_obj);
319 int load_module(void)
322 res = ast_register_application(app_group_count, group_count_exec, group_count_synopsis, group_count_descrip);
323 res |= ast_register_application(app_group_set, group_set_exec, group_set_synopsis, group_set_descrip);
324 res |= ast_register_application(app_group_check, group_check_exec, group_check_synopsis, group_check_descrip);
325 res |= ast_register_application(app_group_match_count, group_match_count_exec, group_match_count_synopsis, group_match_count_descrip);
326 res |= ast_custom_function_register(&group_count_function_obj);
327 res |= ast_custom_function_register(&group_match_count_function_obj);
328 ast_cli_register(&cli_show_channels);
332 char *description(void)
340 STANDARD_USECOUNT(res);
346 return ASTERISK_GPL_KEY;