Fix building of chan_h323 with gcc-3.3
[asterisk/asterisk.git] / funcs / func_groupcount.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * See http://www.asterisk.org for more information about
7  * the Asterisk project. Please do not directly contact
8  * any of the maintainers of this project for assistance;
9  * the project provides a web site, mailing lists and IRC
10  * channels for your use.
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License Version 2. See the LICENSE file
14  * at the top of the source tree.
15  */
16
17 /*! \file
18  *
19  * \brief Channel group related dialplan functions
20  * 
21  * \ingroup functions
22  */
23
24 #include "asterisk.h"
25
26 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
27
28 #include "asterisk/module.h"
29 #include "asterisk/channel.h"
30 #include "asterisk/pbx.h"
31 #include "asterisk/utils.h"
32 #include "asterisk/app.h"
33
34 /*** DOCUMENTATION
35         <function name="GROUP_COUNT" language="en_US">
36                 <synopsis>
37                         Counts the number of channels in the specified group.
38                 </synopsis>
39                 <syntax argsep="@">
40                         <parameter name="groupname">
41                                 <para>Group name.</para>
42                         </parameter>
43                         <parameter name="category">
44                                 <para>Category name</para>
45                         </parameter>
46                 </syntax>
47                 <description>
48                         <para>Calculates the group count for the specified group, or uses the
49                         channel's current group if not specifed (and non-empty).</para>
50                 </description>
51         </function>
52         <function name="GROUP_MATCH_COUNT" language="en_US">
53                 <synopsis>
54                         Counts the number of channels in the groups matching the specified pattern.
55                 </synopsis>
56                 <syntax argsep="@">
57                         <parameter name="groupmatch" required="true">
58                                 <para>A standard regular expression used to match a group name.</para>
59                         </parameter>
60                         <parameter name="category">
61                                 <para>Category name.</para>
62                         </parameter>
63                 </syntax>
64                 <description>
65                         <para>Calculates the group count for all groups that match the specified pattern.
66                         Uses standard regular expression matching (see regex(7)).</para>
67                 </description>
68         </function>
69         <function name="GROUP" language="en_US">
70                 <synopsis>
71                         Gets or sets the channel group.
72                 </synopsis>
73                 <syntax>
74                         <parameter name="category">
75                                 <para>Category name.</para>
76                         </parameter>
77                 </syntax>
78                 <description>
79                         <para><replaceable>category</replaceable> can be employed for more fine grained group management. Each channel 
80                         can only be member of exactly one group per <replaceable>category</replaceable>.</para>
81                 </description>
82         </function>
83         <function name="GROUP_LIST" language="en_US">
84                 <synopsis>
85                         Gets a list of the groups set on a channel.
86                 </synopsis>
87                 <syntax />
88                 <description>
89                         <para>Gets a list of the groups set on a channel.</para>
90                 </description>
91         </function>
92
93  ***/
94
95 static int group_count_function_read(struct ast_channel *chan, const char *cmd,
96                                      char *data, char *buf, size_t len)
97 {
98         int ret = -1;
99         int count = -1;
100         char group[80] = "", category[80] = "";
101
102         ast_app_group_split_group(data, group, sizeof(group), category,
103                                   sizeof(category));
104
105         /* If no group has been provided let's find one */
106         if (ast_strlen_zero(group)) {
107                 struct ast_group_info *gi = NULL;
108
109                 ast_app_group_list_rdlock();
110                 for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
111                         if (gi->chan != chan)
112                                 continue;
113                         if (ast_strlen_zero(category) || (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, category)))
114                                 break;
115                 }
116                 if (gi) {
117                         ast_copy_string(group, gi->group, sizeof(group));
118                         if (!ast_strlen_zero(gi->category))
119                                 ast_copy_string(category, gi->category, sizeof(category));
120                 }
121                 ast_app_group_list_unlock();
122         }
123
124         if ((count = ast_app_group_get_count(group, category)) == -1) {
125                 ast_log(LOG_NOTICE, "No group could be found for channel '%s'\n", chan->name);
126         } else {
127                 snprintf(buf, len, "%d", count);
128                 ret = 0;
129         }
130
131         return ret;
132 }
133
134 static struct ast_custom_function group_count_function = {
135         .name = "GROUP_COUNT",
136         .read = group_count_function_read,
137 };
138
139 static int group_match_count_function_read(struct ast_channel *chan,
140                                            const char *cmd, char *data, char *buf,
141                                            size_t len)
142 {
143         int count;
144         char group[80] = "";
145         char category[80] = "";
146
147         ast_app_group_split_group(data, group, sizeof(group), category,
148                                   sizeof(category));
149
150         if (!ast_strlen_zero(group)) {
151                 count = ast_app_group_match_get_count(group, category);
152                 snprintf(buf, len, "%d", count);
153                 return 0;
154         }
155
156         return -1;
157 }
158
159 static struct ast_custom_function group_match_count_function = {
160         .name = "GROUP_MATCH_COUNT",
161         .read = group_match_count_function_read,
162         .write = NULL,
163 };
164
165 static int group_function_read(struct ast_channel *chan, const char *cmd,
166                                char *data, char *buf, size_t len)
167 {
168         int ret = -1;
169         struct ast_group_info *gi = NULL;
170         
171         ast_app_group_list_rdlock();
172         
173         for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
174                 if (gi->chan != chan)
175                         continue;
176                 if (ast_strlen_zero(data))
177                         break;
178                 if (!ast_strlen_zero(gi->category) && !strcasecmp(gi->category, data))
179                         break;
180         }
181         
182         if (gi) {
183                 ast_copy_string(buf, gi->group, len);
184                 ret = 0;
185         }
186         
187         ast_app_group_list_unlock();
188         
189         return ret;
190 }
191
192 static int group_function_write(struct ast_channel *chan, const char *cmd,
193                                 char *data, const char *value)
194 {
195         char grpcat[256];
196
197         if (!ast_strlen_zero(data)) {
198                 snprintf(grpcat, sizeof(grpcat), "%s@%s", value, data);
199         } else {
200                 ast_copy_string(grpcat, value, sizeof(grpcat));
201         }
202
203         if (ast_app_group_set_channel(chan, grpcat))
204                 ast_log(LOG_WARNING,
205                                 "Setting a group requires an argument (group name)\n");
206
207         return 0;
208 }
209
210 static struct ast_custom_function group_function = {
211         .name = "GROUP",
212         .read = group_function_read,
213         .write = group_function_write,
214 };
215
216 static int group_list_function_read(struct ast_channel *chan, const char *cmd,
217                                     char *data, char *buf, size_t len)
218 {
219         struct ast_group_info *gi = NULL;
220         char tmp1[1024] = "";
221         char tmp2[1024] = "";
222
223         if (!chan)
224                 return -1;
225
226         ast_app_group_list_rdlock();
227
228         for (gi = ast_app_group_list_head(); gi; gi = AST_LIST_NEXT(gi, group_list)) {
229                 if (gi->chan != chan)
230                         continue;
231                 if (!ast_strlen_zero(tmp1)) {
232                         ast_copy_string(tmp2, tmp1, sizeof(tmp2));
233                         if (!ast_strlen_zero(gi->category))
234                                 snprintf(tmp1, sizeof(tmp1), "%s %s@%s", tmp2, gi->group, gi->category);
235                         else
236                                 snprintf(tmp1, sizeof(tmp1), "%s %s", tmp2, gi->group);
237                 } else {
238                         if (!ast_strlen_zero(gi->category))
239                                 snprintf(tmp1, sizeof(tmp1), "%s@%s", gi->group, gi->category);
240                         else
241                                 snprintf(tmp1, sizeof(tmp1), "%s", gi->group);
242                 }
243         }
244         
245         ast_app_group_list_unlock();
246
247         ast_copy_string(buf, tmp1, len);
248
249         return 0;
250 }
251
252 static struct ast_custom_function group_list_function = {
253         .name = "GROUP_LIST",
254         .read = group_list_function_read,
255         .write = NULL,
256 };
257
258 static int unload_module(void)
259 {
260         int res = 0;
261
262         res |= ast_custom_function_unregister(&group_count_function);
263         res |= ast_custom_function_unregister(&group_match_count_function);
264         res |= ast_custom_function_unregister(&group_list_function);
265         res |= ast_custom_function_unregister(&group_function);
266
267         return res;
268 }
269
270 static int load_module(void)
271 {
272         int res = 0;
273
274         res |= ast_custom_function_register(&group_count_function);
275         res |= ast_custom_function_register(&group_match_count_function);
276         res |= ast_custom_function_register(&group_list_function);
277         res |= ast_custom_function_register(&group_function);
278
279         return res;
280 }
281
282 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Channel group dialplan functions");