#include "asterisk.h"
#include <sys/stat.h>
#include "asterisk/module.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/utils.h"
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
#include "asterisk/astdb.h"
Go to the source code of this file.
Data Structures | |
struct | group |
struct | group_entry |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
static int | dialgroup_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | dialgroup_refreshdb (struct ast_channel *chan, const char *cdialgroup) |
static int | dialgroup_write (struct ast_channel *chan, const char *cmd, char *data, const char *cvalue) |
static int | entry_cmp_fn (void *obj1, void *name2, int flags) |
static int | entry_hash_fn (const void *obj, const int flags) |
static int | group_cmp_fn (void *obj1, void *name2, int flags) |
static void | group_destroy (void *vgroup) |
static int | group_hash_fn (const void *obj, const int flags) |
static int | load_module (void) |
static int | unload_module (void) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Dialgroup dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
static struct ast_module_info * | ast_module_info = &__mod_info |
static struct ast_custom_function | dialgroup_function |
static struct ao2_container * | group_container = NULL |
Definition in file func_dialgroup.c.
static void __reg_module | ( | void | ) | [static] |
Definition at line 309 of file func_dialgroup.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 309 of file func_dialgroup.c.
static int dialgroup_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 125 of file func_dialgroup.c.
References ao2_find, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_copy_string(), ast_log(), ast_strlen_zero(), group::entries, group_container, LOG_WARNING, group_entry::name, and OBJ_POINTER.
Referenced by dialgroup_refreshdb().
00126 { 00127 struct ao2_iterator i; 00128 struct group *grhead = ao2_find(group_container, data, 0); 00129 struct group_entry *entry; 00130 size_t bufused = 0; 00131 int trunc_warning = 0; 00132 int res = 0; 00133 00134 if (!grhead) { 00135 if (!ast_strlen_zero(cmd)) { 00136 ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); 00137 } 00138 return -1; 00139 } 00140 00141 buf[0] = '\0'; 00142 00143 i = ao2_iterator_init(grhead->entries, OBJ_POINTER); 00144 while ((entry = ao2_iterator_next(&i))) { 00145 int tmp = strlen(entry->name); 00146 /* Ensure that we copy only complete names, not partials */ 00147 if (len - bufused > tmp + 2) { 00148 if (bufused != 0) 00149 buf[bufused++] = '&'; 00150 ast_copy_string(buf + bufused, entry->name, len - bufused); 00151 bufused += tmp; 00152 } else if (trunc_warning++ == 0) { 00153 if (!ast_strlen_zero(cmd)) { 00154 ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); 00155 } else { 00156 res = 1; 00157 ao2_ref(entry, -1); 00158 break; 00159 } 00160 } 00161 ao2_ref(entry, -1); 00162 } 00163 ao2_iterator_destroy(&i); 00164 00165 return res; 00166 }
static int dialgroup_refreshdb | ( | struct ast_channel * | chan, | |
const char * | cdialgroup | |||
) | [static] |
Definition at line 168 of file func_dialgroup.c.
References ast_db_del(), ast_db_put(), ast_free, ast_realloc, ast_strdupa, ast_strlen_zero(), dialgroup_read(), and len().
00169 { 00170 int len = 500, res = 0; 00171 char *buf = NULL; 00172 char *dialgroup = ast_strdupa(cdialgroup); 00173 00174 do { 00175 len *= 2; 00176 buf = ast_realloc(buf, len); 00177 00178 if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) { 00179 ast_free(buf); 00180 return -1; 00181 } 00182 } while (res == 1); 00183 00184 if (ast_strlen_zero(buf)) { 00185 ast_db_del("dialgroup", cdialgroup); 00186 } else { 00187 ast_db_put("dialgroup", cdialgroup, buf); 00188 } 00189 ast_free(buf); 00190 return 0; 00191 }
static int dialgroup_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | cvalue | |||
) | [static] |
Definition at line 193 of file func_dialgroup.c.
References ao2_alloc, ao2_container_alloc, ao2_find, ao2_link, ao2_ref, ao2_unlink, args, AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_NONSTANDARD_APP_ARGS, AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), group::entries, entry_cmp_fn(), entry_hash_fn(), group_container, group_destroy(), LOG_WARNING, group::name, and value.
Referenced by load_module().
00194 { 00195 struct group *grhead; 00196 struct group_entry *entry; 00197 int j, needrefresh = 1; 00198 AST_DECLARE_APP_ARGS(args, 00199 AST_APP_ARG(group); 00200 AST_APP_ARG(op); 00201 ); 00202 AST_DECLARE_APP_ARGS(inter, 00203 AST_APP_ARG(faces)[100]; 00204 ); 00205 char *value = ast_strdupa(cvalue); 00206 00207 AST_STANDARD_APP_ARGS(args, data); 00208 AST_NONSTANDARD_APP_ARGS(inter, value, '&'); 00209 00210 if (!(grhead = ao2_find(group_container, args.group, 0))) { 00211 /* Create group */ 00212 grhead = ao2_alloc(sizeof(*grhead), group_destroy); 00213 if (!grhead) 00214 return -1; 00215 grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn); 00216 if (!grhead->entries) { 00217 ao2_ref(grhead, -1); 00218 return -1; 00219 } 00220 ast_copy_string(grhead->name, args.group, sizeof(grhead->name)); 00221 ao2_link(group_container, grhead); 00222 } 00223 00224 if (ast_strlen_zero(args.op)) { 00225 /* Wholesale replacement of the group */ 00226 args.op = "add"; 00227 00228 /* Remove all existing */ 00229 ao2_ref(grhead->entries, -1); 00230 if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) { 00231 ao2_unlink(group_container, grhead); 00232 ao2_ref(grhead, -1); 00233 return -1; 00234 } 00235 } 00236 00237 if (strcasecmp(args.op, "add") == 0) { 00238 for (j = 0; j < inter.argc; j++) { 00239 /* Eliminate duplicates */ 00240 if ((entry = ao2_find(grhead->entries, inter.faces[j], 0))) { 00241 ao2_ref(entry, -1); 00242 continue; 00243 } 00244 if ((entry = ao2_alloc(sizeof(*entry), NULL))) { 00245 ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name)); 00246 ao2_link(grhead->entries, entry); 00247 ao2_ref(entry, -1); 00248 } else { 00249 ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name); 00250 } 00251 } 00252 } else if (strncasecmp(args.op, "del", 3) == 0) { 00253 for (j = 0; j < inter.argc; j++) { 00254 if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) { 00255 ao2_ref(entry, -1); 00256 } else { 00257 ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name); 00258 } 00259 } 00260 } else { 00261 ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op); 00262 needrefresh = 0; 00263 } 00264 ao2_ref(grhead, -1); 00265 00266 if (needrefresh) { 00267 dialgroup_refreshdb(chan, args.group); 00268 } 00269 00270 return 0; 00271 }
static int entry_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 115 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group_entry::name, name, and OBJ_POINTER.
Referenced by dialgroup_write().
00116 { 00117 struct group_entry *e1 = obj1, *e2 = name2; 00118 char *name = name2; 00119 if (flags & OBJ_POINTER) 00120 return strcmp(e1->name, e2->name) ? 0 : CMP_MATCH | CMP_STOP; 00121 else 00122 return strcmp(e1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00123 }
static int entry_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 109 of file func_dialgroup.c.
References ast_str_hash(), and group_entry::name.
Referenced by dialgroup_write().
00110 { 00111 const struct group_entry *e = obj; 00112 return ast_str_hash(e->name); 00113 }
static int group_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 99 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group::name, name, and OBJ_POINTER.
Referenced by load_module().
00100 { 00101 struct group *g1 = obj1, *g2 = name2; 00102 char *name = name2; 00103 if (flags & OBJ_POINTER) 00104 return strcmp(g1->name, g2->name) ? 0 : CMP_MATCH | CMP_STOP; 00105 else 00106 return strcmp(g1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00107 }
static void group_destroy | ( | void * | vgroup | ) | [static] |
Definition at line 87 of file func_dialgroup.c.
References ao2_ref, and group.
Referenced by dialgroup_write().
static int group_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 93 of file func_dialgroup.c.
References ast_str_hash(), and group::name.
Referenced by load_module().
00094 { 00095 const struct group *g = obj; 00096 return ast_str_hash(g->name); 00097 }
static int load_module | ( | void | ) | [static] |
Definition at line 286 of file func_dialgroup.c.
References ao2_container_alloc, ast_copy_string(), ast_custom_function_register, ast_db_freetree(), ast_db_gettree(), AST_MAX_EXTENSION, AST_MODULE_LOAD_DECLINE, ast_db_entry::data, dialgroup_function, dialgroup_write(), group_cmp_fn(), group_container, group_hash_fn(), ast_db_entry::key, and ast_db_entry::next.
00287 { 00288 struct ast_db_entry *dbtree, *tmp; 00289 char groupname[AST_MAX_EXTENSION], *ptr; 00290 00291 if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) { 00292 /* Refresh groups from astdb */ 00293 if ((dbtree = ast_db_gettree("dialgroup", NULL))) { 00294 for (tmp = dbtree; tmp; tmp = tmp->next) { 00295 ast_copy_string(groupname, tmp->key, sizeof(groupname)); 00296 if ((ptr = strrchr(groupname, '/'))) { 00297 ptr++; 00298 dialgroup_write(NULL, "", ptr, tmp->data); 00299 } 00300 } 00301 ast_db_freetree(dbtree); 00302 } 00303 return ast_custom_function_register(&dialgroup_function); 00304 } else { 00305 return AST_MODULE_LOAD_DECLINE; 00306 } 00307 }
static int unload_module | ( | void | ) | [static] |
Definition at line 279 of file func_dialgroup.c.
References ao2_ref, ast_custom_function_unregister(), dialgroup_function, and group_container.
00280 { 00281 int res = ast_custom_function_unregister(&dialgroup_function); 00282 ao2_ref(group_container, -1); 00283 return res; 00284 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Dialgroup dialplan function" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 309 of file func_dialgroup.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 309 of file func_dialgroup.c.
struct ast_custom_function dialgroup_function [static] |
Initial value:
{ .name = "DIALGROUP", .read = dialgroup_read, .write = dialgroup_write, }
Definition at line 273 of file func_dialgroup.c.
Referenced by load_module(), and unload_module().
struct ao2_container* group_container = NULL [static] |
Definition at line 76 of file func_dialgroup.c.
Referenced by dialgroup_read(), dialgroup_write(), load_module(), and unload_module().