From c346e0e270e77cfe4ddea30df0b1049cfdfd5bf6 Mon Sep 17 00:00:00 2001 From: Stefan Sayer Date: Fri, 7 Jan 2011 15:06:23 +0100 Subject: [PATCH] moved regex mapping file reading to AmUtils --- core/AmConfig.cpp | 33 ++++------------------------- core/AmConfig.h | 8 ++----- core/AmPlugIn.cpp | 18 ++++------------ core/AmUtils.cpp | 53 +++++++++++++++++++++++++++++++++++++++++++++++ core/AmUtils.h | 17 +++++++++++++++ 5 files changed, 80 insertions(+), 49 deletions(-) diff --git a/core/AmConfig.cpp b/core/AmConfig.cpp index ed630762..8a05fd51 100644 --- a/core/AmConfig.cpp +++ b/core/AmConfig.cpp @@ -38,7 +38,6 @@ #include "AmUtils.h" #include "AmSession.h" -#include #include #include @@ -79,7 +78,7 @@ unsigned int AmConfig::DeadRtpTime = DEAD_RTP_TIME; bool AmConfig::IgnoreRTPXHdrs = false; string AmConfig::Application = ""; AmConfig::ApplicationSelector AmConfig::AppSelect = AmConfig::App_SPECIFIED; -AmConfig::AppMappingVector AmConfig::AppMapping; +RegexMappingVector AmConfig::AppMapping; bool AmConfig::LogSessions = false; bool AmConfig::LogEvents = false; int AmConfig::UnhandledReplyLoglevel = 0; @@ -361,35 +360,11 @@ int AmConfig::readConfiguration() AppSelect = App_MAPPING; string appcfg_fname = ModConfigPath + "app_mapping.conf"; DBG("Loading application mapping...\n"); - std::ifstream appcfg(appcfg_fname.c_str()); - if (!appcfg.good()) { - ERROR("could not load application mapping file at '%s'\n", - appcfg_fname.c_str()); + if (!readRegexMapping(appcfg_fname, "=>", "application mapping", + AppMapping)) { + ERROR("reading application mapping\n"); ret = -1; } - else { - while (!appcfg.eof()) { - string entry; - getline (appcfg,entry); - if (!entry.length() || entry[0] == '#') - continue; - vector re_v = explode(entry, "=>"); - if (re_v.size() != 2) { - ERROR("Incorrect line '%s' in %s: expected format 'regexp=>app_name'\n", - entry.c_str(), appcfg_fname.c_str()); - ret = -1; - } - regex_t app_re; - if (regcomp(&app_re, re_v[0].c_str(), REG_EXTENDED | REG_NOSUB)) { - ERROR("compiling regex '%s' in %s.\n", - re_v[0].c_str(), appcfg_fname.c_str()); - ret = -1; - } - DBG("adding application mapping '%s' => '%s'\n", - re_v[0].c_str(),re_v[1].c_str()); - AppMapping.push_back(make_pair(app_re, re_v[1])); - } - } } else { AppSelect = App_SPECIFIED; } diff --git a/core/AmConfig.h b/core/AmConfig.h index aba0911a..db51c5ee 100644 --- a/core/AmConfig.h +++ b/core/AmConfig.h @@ -31,15 +31,12 @@ #include "AmSdp.h" #include "AmDtmfDetector.h" #include "AmSipDialog.h" +#include "AmUtils.h" #include using std::string; #include -#include -#include - - /** * \brief holds the current configuration. * @@ -127,8 +124,7 @@ struct AmConfig static ApplicationSelector AppSelect; /* this is regex->application mapping is used if App_MAPPING */ - typedef vector > AppMappingVector; - static AppMappingVector AppMapping; + static RegexMappingVector AppMapping; static unsigned int SessionLimit; static unsigned int SessionLimitErrCode; diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp index 190d4f3e..d99bbc9e 100644 --- a/core/AmPlugIn.cpp +++ b/core/AmPlugIn.cpp @@ -780,20 +780,10 @@ AmSessionFactory* AmPlugIn::findSessionFactory(AmSipRequest& req) case AmConfig::App_RURIPARAM: req.cmd = get_header_param(req.r_uri, "app"); break; - case AmConfig::App_MAPPING: - { - req.cmd = ""; - for (AmConfig::AppMappingVector::iterator it = - AmConfig::AppMapping.begin(); - it != AmConfig::AppMapping.end(); it++){ - if (!regexec(&it->first, req.r_uri.c_str(), 0, NULL, 0)) { - DBG("match of r_uri '%s' to application %s\n", - req.r_uri.c_str(), it->second.c_str()); - req.cmd = it->second; - break; - } - } - } break; + case AmConfig::App_MAPPING: + req.cmd = ""; // no match if not found + runRegexMapping(AmConfig::AppMapping, req.r_uri.c_str(), req.cmd); + break; case AmConfig::App_SPECIFIED: req.cmd = AmConfig::Application; break; diff --git a/core/AmUtils.cpp b/core/AmUtils.cpp index 29c024e2..0240899e 100644 --- a/core/AmUtils.cpp +++ b/core/AmUtils.cpp @@ -50,6 +50,8 @@ #include #include +#include + #ifndef UNIX_PATH_MAX #define UNIX_PATH_MAX 104 #endif @@ -1214,3 +1216,54 @@ void add_env_path(const char* name, const string& path) putenv(sol_putenv.c_str()); #endif } + +bool readRegexMapping(const string& fname, const char* separator, + const char* dbg_type, + RegexMappingVector& result) { + std::ifstream appcfg(fname.c_str()); + if (!appcfg.good()) { + ERROR("could not load %s file at '%s'\n", + dbg_type, fname.c_str()); + return false; + } else { + while (!appcfg.eof()) { + string entry; + getline (appcfg,entry); + if (!entry.length()) + continue; + size_t non_wsp_pos = entry.find_first_not_of(" \t"); + if (non_wsp_pos != string::npos && entry[non_wsp_pos] == '#') + continue; + + vector re_v = explode(entry, separator); + if (re_v.size() != 2) { + ERROR("Incorrect line '%s' in %s: expected format 'regexp%sstring'\n", + entry.c_str(), fname.c_str(), separator); + return false; + } + regex_t app_re; + if (regcomp(&app_re, re_v[0].c_str(), REG_EXTENDED | REG_NOSUB)) { + ERROR("compiling regex '%s' in %s.\n", + re_v[0].c_str(), fname.c_str()); + return false; + } + DBG("adding %s '%s' => '%s'\n", + dbg_type, re_v[0].c_str(),re_v[1].c_str()); + result.push_back(make_pair(app_re, re_v[1])); + } + } + return true; +} + +bool runRegexMapping(const RegexMappingVector& mapping, const char* test_s, + string& result) { + for (RegexMappingVector::const_iterator it = mapping.begin(); + it != mapping.end(); it++) { + if (!regexec(&it->first, test_s, 0, NULL, 0)) { + DBG("match of '%s' to %s\n", test_s, it->second.c_str()); + result = it->second; + return true; + } + } + return false; +} diff --git a/core/AmUtils.h b/core/AmUtils.h index 6b7e1e5f..eeceee68 100644 --- a/core/AmUtils.h +++ b/core/AmUtils.h @@ -31,11 +31,14 @@ #include #include #include +#include +#include #include using std::string; #include +#include #define FIFO_PERM S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH @@ -340,6 +343,20 @@ std::vector explode(const string& s, const string& delim, const bool kee /** add a directory to an environement variable */ void add_env_path(const char* name, const string& path); +typedef std::vector > RegexMappingVector; + +/** read a regex=>string mapping from file + @return true on success + */ +bool readRegexMapping(const string& fname, const char* separator, + const char* dbg_type, + RegexMappingVector& result); + +/** run a regex mapping - result is the first matching entry + @return true if matched + */ +bool runRegexMapping(const RegexMappingVector& mapping, const char* test_s, + string& result); #endif // Local Variables: