diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 37c72d6c91e3f6bb36292a3048a29560824c2f7d..aebf7abbc0cc38039f98a18dc246dc48b7833414 100755 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -356,7 +356,7 @@ int ast_matchmore_extension(struct ast_channel *c, const char *context, const ch * Returns 1 on match, 0 on failure */ int ast_extension_match(const char *pattern, const char *extension); - +int ast_extension_close(const char *pattern, const char *data, int needmore); //! Launch a new extension (i.e. new stack) /*! * \param c not important diff --git a/pbx.c b/pbx.c index 5ae63735e9f4adb43be14ed03241886c3d28fb4e..737611af5ad755a9e134ad97aff54568e659a470 100755 --- a/pbx.c +++ b/pbx.c @@ -649,7 +649,7 @@ int ast_extension_match(const char *pattern, const char *data) return match; } -static int extension_close(const char *pattern, const char *data, int needmore) +int ast_extension_close(const char *pattern, const char *data, int needmore) { int match; /* If "data" is longer, it can'be a subset of pattern unless @@ -749,8 +749,8 @@ static struct ast_exten *pbx_find_extension(struct ast_channel *chan, struct ast while(eroot) { /* Match extension */ if ((((action != HELPER_MATCHMORE) && ast_extension_match(eroot->exten, exten)) || - ((action == HELPER_CANMATCH) && (extension_close(eroot->exten, exten, 0))) || - ((action == HELPER_MATCHMORE) && (extension_close(eroot->exten, exten, 1)))) && + ((action == HELPER_CANMATCH) && (ast_extension_close(eroot->exten, exten, 0))) || + ((action == HELPER_MATCHMORE) && (ast_extension_close(eroot->exten, exten, 1)))) && (!eroot->matchcid || matchcid(eroot->cidmatch, callerid))) { e = eroot; if (*status < STATUS_NO_PRIORITY) diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c index 5a828f44a65ab6eb9e06acd6850497b1a4851583..52de08ba8eb0b2e1659b07d19844b0852b6f9e9e 100755 --- a/pbx/pbx_realtime.c +++ b/pbx/pbx_realtime.c @@ -13,6 +13,7 @@ #include <asterisk/logger.h> #include <asterisk/channel.h> #include <asterisk/config.h> +#include <asterisk/config_pvt.h> #include <asterisk/options.h> #include <asterisk/pbx.h> #include <asterisk/module.h> @@ -34,9 +35,9 @@ #include <string.h> #include <errno.h> -#define MODE_MATCH 0 -#define MODE_MATCHMORE 1 -#define MODE_CANMATCH 2 +#define MODE_MATCH 0 +#define MODE_MATCHMORE 1 +#define MODE_CANMATCH 2 static char *tdesc = "Realtime Switch"; @@ -49,7 +50,7 @@ static char *tdesc = "Realtime Switch"; The realtime table should have entries for context,exten,priority,app,args - The realtime table currently does not support patterns or callerid fields. + The realtime table currently does not support callerid fields. */ @@ -86,9 +87,12 @@ static char *tdesc = "Realtime Switch"; static struct ast_variable *realtime_switch_common(const char *table, const char *context, const char *exten, int priority, int mode) { struct ast_variable *var; + struct ast_config *cfg; + struct ast_category *cat; char pri[20]; char *ematch; char rexten[AST_MAX_EXTENSION + 20]=""; + int match; snprintf(pri, sizeof(pri), "%d", priority); switch(mode) { case MODE_MATCHMORE: @@ -104,7 +108,33 @@ static struct ast_variable *realtime_switch_common(const char *table, const char ematch = "exten"; strncpy(rexten, exten, sizeof(rexten) - 1); } - var = ast_load_realtime(table, "context", context, ematch, rexten, "priority", pri, NULL); + var = ast_load_realtime(table, ematch, rexten, "context", context, "priority", pri, NULL); + if (!var) { + cfg = ast_load_realtime_multientry(table, "exten RLIKE", "_.*", "context", context, "priority", pri, NULL); + if (cfg) { + cat = cfg->root; + while(cat) { + switch(mode) { + case MODE_MATCHMORE: + match = ast_extension_close(cat->name, exten, 1); + break; + case MODE_CANMATCH: + match = ast_extension_close(cat->name, exten, 0); + break; + case MODE_MATCH: + default: + match = ast_extension_match(cat->name, exten); + } + if (match) { + var = cat->root; + cat->root = NULL; + break; + } + cat = cat->next; + } + ast_destroy(cfg); + } + } return var; } diff --git a/res/res_config_odbc.c b/res/res_config_odbc.c index 786e14bca108eebc16ec2ea946d88de0af34959b..96d5aacd3ad5647404544fec577aa7cfde86f9c9 100755 --- a/res/res_config_odbc.c +++ b/res/res_config_odbc.c @@ -174,6 +174,8 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * char sql[1024]; char coltitle[256]; char rowdata[2048]; + char *title=NULL; + const char *initfield=NULL; char *op; const char *newparam, *newval; char *stringp; @@ -213,6 +215,9 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * SQLFreeHandle (SQL_HANDLE_STMT, stmt); return NULL; } + initfield = ast_strdupa(newparam); + if (initfield && (op = strchr(initfield, ' '))) + *op = '\0'; newval = va_arg(aq, const char *); if (!strchr(newparam, ' ')) op = " ="; else op = ""; snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE %s%s ?", table, newparam, op); @@ -221,6 +226,8 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " AND %s%s ?", newparam, op); newval = va_arg(aq, const char *); } + if (initfield) + snprintf(sql + strlen(sql), sizeof(sql) - strlen(sql), " ORDER BY %s", initfield); va_end(aq); res = SQLPrepare(stmt, sql, SQL_NTS); if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) { @@ -259,7 +266,7 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * return NULL; } - while (rowcount) { + while (rowcount--) { var = NULL; prev = NULL; res = SQLFetch(stmt); @@ -289,6 +296,8 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * while(stringp) { chunk = strsep(&stringp, ";"); if (chunk && !ast_strlen_zero(ast_strip(chunk))) { + if (initfield && !strcmp(initfield, coltitle) && !title) + title = ast_strdupa(chunk); if (prev) { prev->next = ast_new_variable(coltitle, chunk); if (prev->next) @@ -298,20 +307,20 @@ static struct ast_config *realtime_multi_odbc(const char *database, const char * } } - if (var) { - cat = ast_new_category(""); - if (cat) { - cat->root = var; - if (!cfg) - cfg = ast_new_config(); - if (cfg) - ast_category_append(cfg, cat); - else - ast_category_destroy(cat); - } else { - ast_log(LOG_WARNING, "Out of memory!\n"); - ast_destroy_realtime(var); - } + } + if (var) { + cat = ast_new_category(title ? title : ""); + if (cat) { + cat->root = var; + if (!cfg) + cfg = ast_new_config(); + if (cfg) + ast_category_append(cfg, cat); + else + ast_category_destroy(cat); + } else { + ast_log(LOG_WARNING, "Out of memory!\n"); + ast_destroy_realtime(var); } } }