Sat Sep 16 05:47:40 2006

Asterisk developer's documentation


app_groupcount.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief Group Manipulation Applications
00022  *
00023  * \ingroup applications
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(&regexbuf, 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(&regexbuf, 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(&regexbuf, 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(&regexbuf);
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 }

Generated on Sat Sep 16 05:47:40 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7