From 8f2b687a9523730a0bd9a3506f930c8569e1ef4c Mon Sep 17 00:00:00 2001 From: Mark Spencer <markster@digium.com> Date: Wed, 24 Nov 2004 03:07:08 +0000 Subject: [PATCH] Make realtime pbx understand patterns. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4326 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/pbx.h | 2 +- pbx.c | 6 +++--- pbx/pbx_realtime.c | 40 +++++++++++++++++++++++++++++++++++----- res/res_config_odbc.c | 39 ++++++++++++++++++++++++--------------- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 37c72d6c91..aebf7abbc0 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 5ae63735e9..737611af5a 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 5a828f44a6..52de08ba8e 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 786e14bca1..96d5aacd3a 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); } } } -- GitLab