diff --git a/CHANGES b/CHANGES
index 6085d327a9..3ba5864600 100644
--- a/CHANGES
+++ b/CHANGES
@@ -40,6 +40,11 @@ Dialplan Variables
ASTAGIDIR, ASTSPOOLDIR, ASTRUNDIR, ASTLOGDIR which hold the equivalent
variables from asterisk.conf.
+Dialplan Functions
+------------------
+ * Added DB_KEYS, which lists the next set of keys in the Asterisk database
+ hierarchy.
+
libpri channel driver (chan_dahdi) DAHDI changes
--------------------------
* Added moh_signaling option to specify what to do when the channel's bridged
diff --git a/funcs/func_db.c b/funcs/func_db.c
index 736fb0d752..a932cf5b15 100644
--- a/funcs/func_db.c
+++ b/funcs/func_db.c
@@ -81,6 +81,19 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
[DB]
+
+
+ Obtain a list of keys within the Asterisk database.
+
+
+
+
+
+ This function will return a comma-separated list of keys existing
+ at the prefix specified within the Asterisk database. If no argument is
+ provided, then a list of key families will be returned.
+
+
Return a value from the database and delete it.
@@ -204,6 +217,61 @@ static struct ast_custom_function db_exists_function = {
.read_max = 2,
};
+static int function_db_keys(struct ast_channel *chan, const char *cmd, char *parse, struct ast_str **result, ssize_t maxlen)
+{
+ size_t parselen = strlen(parse);
+ struct ast_db_entry *dbe, *orig_dbe;
+ struct ast_str *escape_buf = NULL;
+ const char *last = "";
+
+ /* Remove leading and trailing slashes */
+ while (parse[0] == '/') {
+ parse++;
+ parselen--;
+ }
+ while (parse[parselen - 1] == '/') {
+ parse[--parselen] = '\0';
+ }
+
+ ast_str_reset(*result);
+
+ /* Nothing within the database at that prefix? */
+ if (!(orig_dbe = dbe = ast_db_gettree(parse, NULL))) {
+ return 0;
+ }
+
+ for (; dbe; dbe = dbe->next) {
+ /* Find the current component */
+ char *curkey = &dbe->key[parselen + 1], *slash;
+ if (*curkey == '/') {
+ curkey++;
+ }
+ /* Remove everything after the current component */
+ if ((slash = strchr(curkey, '/'))) {
+ *slash = '\0';
+ }
+
+ /* Skip duplicates */
+ if (!strcasecmp(last, curkey)) {
+ continue;
+ }
+ last = curkey;
+
+ if (orig_dbe != dbe) {
+ ast_str_append(result, maxlen, ",");
+ }
+ ast_str_append_escapecommas(result, maxlen, curkey, strlen(curkey));
+ }
+ ast_db_freetree(orig_dbe);
+ ast_free(escape_buf);
+ return 0;
+}
+
+static struct ast_custom_function db_keys_function = {
+ .name = "DB_KEYS",
+ .read2 = function_db_keys,
+};
+
static int function_db_delete(struct ast_channel *chan, const char *cmd,
char *parse, char *buf, size_t len)
{
@@ -252,6 +320,7 @@ static int unload_module(void)
res |= ast_custom_function_unregister(&db_function);
res |= ast_custom_function_unregister(&db_exists_function);
res |= ast_custom_function_unregister(&db_delete_function);
+ res |= ast_custom_function_unregister(&db_keys_function);
return res;
}
@@ -263,6 +332,7 @@ static int load_module(void)
res |= ast_custom_function_register(&db_function);
res |= ast_custom_function_register(&db_exists_function);
res |= ast_custom_function_register(&db_delete_function);
+ res |= ast_custom_function_register(&db_keys_function);
return res;
}