Index: funcs/func_dialgroup.c =================================================================== --- funcs/func_dialgroup.c (revision 133236) +++ funcs/func_dialgroup.c (working copy) @@ -37,6 +37,7 @@ #include "asterisk/utils.h" #include "asterisk/app.h" #include "asterisk/astobj2.h" +#include "asterisk/astdb.h" static struct ao2_container *group_container = NULL; @@ -94,13 +95,16 @@ struct group_entry *entry; size_t bufused = 0; int trunc_warning = 0; + int res = 0; if (!grhead) { - ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); + if (!ast_strlen_zero(cmd)) { + ast_log(LOG_WARNING, "No such dialgroup '%s'\n", data); + } return -1; } - i = ao2_iterator_init(grhead->entries, 0); + i = ao2_iterator_init(grhead->entries, OBJ_POINTER); while ((entry = ao2_iterator_next(&i))) { int tmp = strlen(entry->name); /* Ensure that we copy only complete names, not partials */ @@ -109,10 +113,39 @@ buf[bufused++] = '&'; ast_copy_string(buf + bufused, entry->name, len - bufused); bufused += tmp; - } else if (trunc_warning++ == 0) - ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); + } else if (trunc_warning++ == 0) { + if (!ast_strlen_zero(cmd)) { + ast_log(LOG_WARNING, "Dialgroup '%s' is too large. Truncating list.\n", data); + } else { + res = 1; + ao2_ref(entry, -1); + break; + } + } + ao2_ref(entry, -1); } + return res; +} + +static int dialgroup_refreshdb(struct ast_channel *chan, const char *cdialgroup) +{ + int len = 500, res = 0; + char *buf = NULL; + char *dialgroup = ast_strdupa(cdialgroup); + + do { + len *= 2; + buf = ast_realloc(buf, len); + + if ((res = dialgroup_read(chan, "", dialgroup, buf, len)) < 0) { + ast_free(buf); + return -1; + } + } while (res == 1); + + ast_db_put("dialgroup", cdialgroup, buf); + ast_free(buf); return 0; } @@ -133,7 +166,7 @@ AST_STANDARD_APP_ARGS(args, data); AST_NONSTANDARD_APP_ARGS(inter, value, '&'); - if (!(grhead = ao2_find(group_container, data, 0))) { + if (!(grhead = ao2_find(group_container, args.group, 0))) { /* Create group */ grhead = ao2_alloc(sizeof(*grhead), group_destroy); if (!grhead) @@ -153,8 +186,13 @@ /* Remove all existing */ ao2_ref(grhead->entries, -1); - if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) + ao2_unlink(group_container, grhead); + dialgroup_refreshdb(chan, args.group); + if (!(grhead->entries = ao2_container_alloc(37, entry_hash_fn, entry_cmp_fn))) { + ao2_ref(grhead, -1); return -1; + } + ao2_link(group_container, grhead); } if (strcasecmp(args.op, "add") == 0) { @@ -162,18 +200,25 @@ if ((entry = ao2_alloc(sizeof(*entry), NULL))) { ast_copy_string(entry->name, inter.faces[j], sizeof(entry->name)); ao2_link(grhead->entries, entry); - } else + ao2_ref(entry, -1); + dialgroup_refreshdb(chan, args.group); + } else { ast_log(LOG_WARNING, "Unable to add '%s' to dialgroup '%s'\n", inter.faces[j], grhead->name); + } } } else if (strncasecmp(args.op, "del", 3) == 0) { for (j = 0; j < inter.argc; j++) { - if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) + if ((entry = ao2_find(grhead->entries, inter.faces[j], OBJ_UNLINK))) { ao2_ref(entry, -1); - else + dialgroup_refreshdb(chan, args.group); + } else { ast_log(LOG_WARNING, "Interface '%s' not found in dialgroup '%s'\n", inter.faces[j], grhead->name); + } } - } else + } else { ast_log(LOG_ERROR, "Unrecognized operation: %s\n", args.op); + } + ao2_ref(grhead, -1); return 0; } @@ -211,10 +256,25 @@ static int load_module(void) { - if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) + struct ast_db_entry *dbtree, *tmp; + char groupname[AST_MAX_EXTENSION], *ptr; + + if ((group_container = ao2_container_alloc(37, group_hash_fn, group_cmp_fn))) { + /* Refresh groups from astdb */ + if ((dbtree = ast_db_gettree("dialgroup", NULL))) { + for (tmp = dbtree; tmp; tmp = tmp->next) { + ast_copy_string(groupname, tmp->key, sizeof(groupname)); + if ((ptr = strrchr(groupname, '/'))) { + ptr++; + dialgroup_write(NULL, "", ptr, tmp->data); + } + } + ast_db_freetree(dbtree); + } return ast_custom_function_register(&dialgroup_function); - else + } else { return AST_MODULE_LOAD_DECLINE; + } } AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialgroup dialplan function");