#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 = "ac1f6a56484a8820659555499174e588" , .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 314 of file func_dialgroup.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 314 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 129 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, and group_entry::name.
Referenced by dialgroup_refreshdb().
00130 { 00131 struct ao2_iterator i; 00132 struct group *grhead = ao2_find(group_container, data, 0); 00133 struct group_entry *entry; 00134 size_t bufused = 0; 00135 int trunc_warning = 0; 00136 int res = 0; 00137 00138 if (!grhead) { 00139 if (!ast_strlen_zero(cmd)) { 00140 ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); 00141 } 00142 return -1; 00143 } 00144 00145 buf[0] = '\0'; 00146 00147 i = ao2_iterator_init(grhead->entries, 0); 00148 while ((entry = ao2_iterator_next(&i))) { 00149 int tmp = strlen(entry->name); 00150 /* Ensure that we copy only complete names, not partials */ 00151 if (len - bufused > tmp + 2) { 00152 if (bufused != 0) 00153 buf[bufused++] = '&'; 00154 ast_copy_string(buf + bufused, entry->name, len - bufused); 00155 bufused += tmp; 00156 } else if (trunc_warning++ == 0) { 00157 if (!ast_strlen_zero(cmd)) { 00158 ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); 00159 } else { 00160 res = 1; 00161 ao2_ref(entry, -1); 00162 break; 00163 } 00164 } 00165 ao2_ref(entry, -1); 00166 } 00167 ao2_iterator_destroy(&i); 00168 ao2_ref(grhead, -1); 00169 00170 return res; 00171 }
static int dialgroup_refreshdb | ( | struct ast_channel * | chan, | |
const char * | cdialgroup | |||
) | [static] |
Definition at line 173 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().
00174 { 00175 int len = 500, res = 0; 00176 char *buf = NULL; 00177 char *dialgroup = ast_strdupa(cdialgroup); 00178 00179 do { 00180 len *= 2; 00181 buf = ast_realloc(buf, len); 00182 00183 if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) { 00184 ast_free(buf); 00185 return -1; 00186 } 00187 } while (res == 1); 00188 00189 if (ast_strlen_zero(buf)) { 00190 ast_db_del("dialgroup", cdialgroup); 00191 } else { 00192 ast_db_put("dialgroup", cdialgroup, buf); 00193 } 00194 ast_free(buf); 00195 return 0; 00196 }
static int dialgroup_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | cvalue | |||
) | [static] |
Definition at line 198 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().
00199 { 00200 struct group *grhead; 00201 struct group_entry *entry; 00202 int j, needrefresh = 1; 00203 AST_DECLARE_APP_ARGS(args, 00204 AST_APP_ARG(group); 00205 AST_APP_ARG(op); 00206 ); 00207 AST_DECLARE_APP_ARGS(inter, 00208 AST_APP_ARG(faces)[100]; 00209 ); 00210 char *value = ast_strdupa(cvalue); 00211 00212 AST_STANDARD_APP_ARGS(args, data); 00213 AST_NONSTANDARD_APP_ARGS(inter, value, '&'); 00214 00215 if (!(grhead = ao2_find(group_container, args.group, 0))) { 00216 /* Create group */ 00217 grhead = ao2_alloc(sizeof(*grhead), group_destroy); 00218 if (!grhead) 00219 return -1; 00220 grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn); 00221 if (!grhead->entries) { 00222 ao2_ref(grhead, -1); 00223 return -1; 00224 } 00225 ast_copy_string(grhead->name, args.group, sizeof(grhead->name)); 00226 ao2_link(group_container, grhead); 00227 } 00228 00229 if (ast_strlen_zero(args.op)) { 00230 /* Wholesale replacement of the group */ 00231 args.op = "add"; 00232 00233 /* Remove all existing */ 00234 ao2_ref(grhead->entries, -1); 00235 if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) { 00236 ao2_unlink(group_container, grhead); 00237 ao2_ref(grhead, -1); 00238 return -1; 00239 } 00240 } 00241 00242 if (strcasecmp(args.op, "add") == 0) { 00243 for (j = 0; j < inter.argc; j++) { 00244 /* Eliminate duplicates */ 00245 if ((entry = ao2_find(grhead->entries, inter.faces[j], 0))) { 00246 ao2_ref(entry, -1); 00247 continue; 00248 } 00249 if ((entry = ao2_alloc(sizeof(*entry), NULL))) { 00250 ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name)); 00251 ao2_link(grhead->entries, entry); 00252 ao2_ref(entry, -1); 00253 } else { 00254 ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name); 00255 } 00256 } 00257 } else if (strncasecmp(args.op, "del", 3) == 0) { 00258 for (j = 0; j < inter.argc; j++) { 00259 if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) { 00260 ao2_ref(entry, -1); 00261 } else { 00262 ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name); 00263 } 00264 } 00265 } else { 00266 ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op); 00267 needrefresh = 0; 00268 } 00269 ao2_ref(grhead, -1); 00270 00271 if (needrefresh) { 00272 dialgroup_refreshdb(chan, args.group); 00273 } 00274 00275 return 0; 00276 }
static int entry_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 119 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group_entry::name, name, and OBJ_POINTER.
Referenced by dialgroup_write().
00120 { 00121 struct group_entry *e1 = obj1, *e2 = name2; 00122 char *name = name2; 00123 if (flags & OBJ_POINTER) 00124 return strcmp(e1->name, e2->name) ? 0 : CMP_MATCH | CMP_STOP; 00125 else 00126 return strcmp(e1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00127 }
static int entry_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 113 of file func_dialgroup.c.
References ast_str_hash(), and group_entry::name.
Referenced by dialgroup_write().
00114 { 00115 const struct group_entry *e = obj; 00116 return ast_str_hash(e->name); 00117 }
static int group_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 103 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group::name, name, and OBJ_POINTER.
Referenced by load_module().
00104 { 00105 struct group *g1 = obj1, *g2 = name2; 00106 char *name = name2; 00107 if (flags & OBJ_POINTER) 00108 return strcmp(g1->name, g2->name) ? 0 : CMP_MATCH | CMP_STOP; 00109 else 00110 return strcmp(g1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00111 }
static void group_destroy | ( | void * | vgroup | ) | [static] |
Definition at line 91 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 97 of file func_dialgroup.c.
References ast_str_hash(), and group::name.
Referenced by load_module().
00098 { 00099 const struct group *g = obj; 00100 return ast_str_hash(g->name); 00101 }
static int load_module | ( | void | ) | [static] |
Definition at line 291 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.
00292 { 00293 struct ast_db_entry *dbtree, *tmp; 00294 char groupname[AST_MAX_EXTENSION], *ptr; 00295 00296 if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) { 00297 /* Refresh groups from astdb */ 00298 if ((dbtree = ast_db_gettree("dialgroup", NULL))) { 00299 for (tmp = dbtree; tmp; tmp = tmp->next) { 00300 ast_copy_string(groupname, tmp->key, sizeof(groupname)); 00301 if ((ptr = strrchr(groupname, '/'))) { 00302 ptr++; 00303 dialgroup_write(NULL, "", ptr, tmp->data); 00304 } 00305 } 00306 ast_db_freetree(dbtree); 00307 } 00308 return ast_custom_function_register(&dialgroup_function); 00309 } else { 00310 return AST_MODULE_LOAD_DECLINE; 00311 } 00312 }
static int unload_module | ( | void | ) | [static] |
Definition at line 284 of file func_dialgroup.c.
References ao2_ref, ast_custom_function_unregister(), dialgroup_function, and group_container.
00285 { 00286 int res = ast_custom_function_unregister(&dialgroup_function); 00287 ao2_ref(group_container, -1); 00288 return res; 00289 }
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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 314 of file func_dialgroup.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 314 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 278 of file func_dialgroup.c.
Referenced by load_module(), and unload_module().
struct ao2_container* group_container = NULL [static] |
Definition at line 80 of file func_dialgroup.c.
Referenced by dialgroup_read(), dialgroup_write(), load_module(), and unload_module().