#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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } |
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 287 of file func_dialgroup.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 287 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 91 of file func_dialgroup.c.
References ao2_find, 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().
00092 { 00093 struct ao2_iterator i; 00094 struct group *grhead = ao2_find(group_container, data, 0); 00095 struct group_entry *entry; 00096 size_t bufused = 0; 00097 int trunc_warning = 0; 00098 int res = 0; 00099 00100 if (!grhead) { 00101 if (!ast_strlen_zero(cmd)) { 00102 ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); 00103 } 00104 return -1; 00105 } 00106 00107 buf[0] = '\0'; 00108 00109 i = ao2_iterator_init(grhead->entries, OBJ_POINTER); 00110 while ((entry = ao2_iterator_next(&i))) { 00111 int tmp = strlen(entry->name); 00112 /* Ensure that we copy only complete names, not partials */ 00113 if (len - bufused > tmp + 2) { 00114 if (bufused != 0) 00115 buf[bufused++] = '&'; 00116 ast_copy_string(buf + bufused, entry->name, len - bufused); 00117 bufused += tmp; 00118 } else if (trunc_warning++ == 0) { 00119 if (!ast_strlen_zero(cmd)) { 00120 ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); 00121 } else { 00122 res = 1; 00123 ao2_ref(entry, -1); 00124 break; 00125 } 00126 } 00127 ao2_ref(entry, -1); 00128 } 00129 00130 return res; 00131 }
static int dialgroup_refreshdb | ( | struct ast_channel * | chan, | |
const char * | cdialgroup | |||
) | [static] |
Definition at line 133 of file func_dialgroup.c.
References ast_db_del(), ast_db_put(), ast_free, ast_realloc, ast_strdupa, ast_strlen_zero(), buf, chan, dialgroup_read(), and len().
00134 { 00135 int len = 500, res = 0; 00136 char *buf = NULL; 00137 char *dialgroup = ast_strdupa(cdialgroup); 00138 00139 do { 00140 len *= 2; 00141 buf = ast_realloc(buf, len); 00142 00143 if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) { 00144 ast_free(buf); 00145 return -1; 00146 } 00147 } while (res == 1); 00148 00149 if (ast_strlen_zero(buf)) { 00150 ast_db_del("dialgroup", cdialgroup); 00151 } else { 00152 ast_db_put("dialgroup", cdialgroup, buf); 00153 } 00154 ast_free(buf); 00155 return 0; 00156 }
static int dialgroup_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | cvalue | |||
) | [static] |
Definition at line 158 of file func_dialgroup.c.
References ao2_alloc, ao2_container_alloc, ao2_find, ao2_link, ao2_ref, ao2_unlink, 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 OBJ_UNLINK.
Referenced by load_module().
00159 { 00160 struct group *grhead; 00161 struct group_entry *entry; 00162 int j, needrefresh = 1; 00163 AST_DECLARE_APP_ARGS(args, 00164 AST_APP_ARG(group); 00165 AST_APP_ARG(op); 00166 ); 00167 AST_DECLARE_APP_ARGS(inter, 00168 AST_APP_ARG(faces)[100]; 00169 ); 00170 char *value = ast_strdupa(cvalue); 00171 00172 AST_STANDARD_APP_ARGS(args, data); 00173 AST_NONSTANDARD_APP_ARGS(inter, value, '&'); 00174 00175 if (!(grhead = ao2_find(group_container, args.group, 0))) { 00176 /* Create group */ 00177 grhead = ao2_alloc(sizeof(*grhead), group_destroy); 00178 if (!grhead) 00179 return -1; 00180 grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn); 00181 if (!grhead->entries) { 00182 ao2_ref(grhead, -1); 00183 return -1; 00184 } 00185 ast_copy_string(grhead->name, args.group, sizeof(grhead->name)); 00186 ao2_link(group_container, grhead); 00187 } 00188 00189 if (ast_strlen_zero(args.op)) { 00190 /* Wholesale replacement of the group */ 00191 args.op = "add"; 00192 00193 /* Remove all existing */ 00194 ao2_ref(grhead->entries, -1); 00195 if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) { 00196 ao2_unlink(group_container, grhead); 00197 ao2_ref(grhead, -1); 00198 return -1; 00199 } 00200 } 00201 00202 if (strcasecmp(args.op, "add") == 0) { 00203 for (j = 0; j < inter.argc; j++) { 00204 if ((entry = ao2_alloc(sizeof(*entry), NULL))) { 00205 ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name)); 00206 ao2_link(grhead->entries, entry); 00207 ao2_ref(entry, -1); 00208 } else { 00209 ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name); 00210 } 00211 } 00212 } else if (strncasecmp(args.op, "del", 3) == 0) { 00213 for (j = 0; j < inter.argc; j++) { 00214 if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) { 00215 ao2_ref(entry, -1); 00216 } else { 00217 ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name); 00218 } 00219 } 00220 } else { 00221 ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op); 00222 needrefresh = 0; 00223 } 00224 ao2_ref(grhead, -1); 00225 00226 if (needrefresh) { 00227 dialgroup_refreshdb(chan, args.group); 00228 } 00229 00230 return 0; 00231 }
static int entry_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 81 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group_entry::name, name, and OBJ_POINTER.
Referenced by dialgroup_write().
00082 { 00083 struct group_entry *e1 = obj1, *e2 = name2; 00084 char *name = name2; 00085 if (flags & OBJ_POINTER) 00086 return strcmp(e1->name, e2->name) ? 0 : CMP_MATCH | CMP_STOP; 00087 else 00088 return strcmp(e1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00089 }
static int entry_hash_fn | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 75 of file func_dialgroup.c.
References ast_str_hash(), and group_entry::name.
Referenced by dialgroup_write().
00076 { 00077 const struct group_entry *e = obj; 00078 return ast_str_hash(e->name); 00079 }
static int group_cmp_fn | ( | void * | obj1, | |
void * | name2, | |||
int | flags | |||
) | [static] |
Definition at line 65 of file func_dialgroup.c.
References CMP_MATCH, CMP_STOP, group::name, name, and OBJ_POINTER.
Referenced by load_module().
00066 { 00067 struct group *g1 = obj1, *g2 = name2; 00068 char *name = name2; 00069 if (flags & OBJ_POINTER) 00070 return strcmp(g1->name, g2->name) ? 0 : CMP_MATCH | CMP_STOP; 00071 else 00072 return strcmp(g1->name, name) ? 0 : CMP_MATCH | CMP_STOP; 00073 }
static void group_destroy | ( | void * | vgroup | ) | [static] |
Definition at line 53 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 59 of file func_dialgroup.c.
References ast_str_hash(), and group::name.
Referenced by load_module().
00060 { 00061 const struct group *g = obj; 00062 return ast_str_hash(g->name); 00063 }
static int load_module | ( | void | ) | [static] |
Definition at line 264 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.
00265 { 00266 struct ast_db_entry *dbtree, *tmp; 00267 char groupname[AST_MAX_EXTENSION], *ptr; 00268 00269 if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) { 00270 /* Refresh groups from astdb */ 00271 if ((dbtree = ast_db_gettree("dialgroup", NULL))) { 00272 for (tmp = dbtree; tmp; tmp = tmp->next) { 00273 ast_copy_string(groupname, tmp->key, sizeof(groupname)); 00274 if ((ptr = strrchr(groupname, '/'))) { 00275 ptr++; 00276 dialgroup_write(NULL, "", ptr, tmp->data); 00277 } 00278 } 00279 ast_db_freetree(dbtree); 00280 } 00281 return ast_custom_function_register(&dialgroup_function); 00282 } else { 00283 return AST_MODULE_LOAD_DECLINE; 00284 } 00285 }
static int unload_module | ( | void | ) | [static] |
Definition at line 257 of file func_dialgroup.c.
References ao2_ref, ast_custom_function_unregister(), dialgroup_function, and group_container.
00258 { 00259 int res = ast_custom_function_unregister(&dialgroup_function); 00260 ao2_ref(group_container, -1); 00261 return res; 00262 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 287 of file func_dialgroup.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 287 of file func_dialgroup.c.
struct ast_custom_function dialgroup_function [static] |
struct ao2_container* group_container = NULL [static] |
Definition at line 42 of file func_dialgroup.c.
Referenced by dialgroup_read(), dialgroup_write(), load_module(), and unload_module().