Make realtime pbx understand patterns.
authorMark Spencer <markster@digium.com>
Wed, 24 Nov 2004 03:07:08 +0000 (03:07 +0000)
committerMark Spencer <markster@digium.com>
Wed, 24 Nov 2004 03:07:08 +0000 (03:07 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4326 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/pbx.h
pbx.c
pbx/pbx_realtime.c
res/res_config_odbc.c

index 37c72d6..aebf7ab 100755 (executable)
@@ -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 5ae6373..737611a 100755 (executable)
--- 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)
index 5a828f4..52de08b 100755 (executable)
@@ -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;
 }
 
index 786e14b..96d5aac 100755 (executable)
@@ -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);
                        }
                }
        }