Convert to use stringfields. Still some more work to do on config load/reload.
authorSean Bright <sean@malleable.com>
Mon, 16 Jun 2008 17:14:11 +0000 (17:14 +0000)
committerSean Bright <sean@malleable.com>
Mon, 16 Jun 2008 17:14:11 +0000 (17:14 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@123044 65c4cc65-6c06-0410-ace0-fbb531ad65f3

cdr/cdr_tds.c

index 7876d65..6ac5c09 100644 (file)
@@ -84,16 +84,24 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 static char *name = "mssql";
 static char *config = "cdr_tds.conf";
 
-static char *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *charset = NULL, *language = NULL;
-static char *table = NULL;
-
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(tds_lock);
+struct cdr_tds_config {
+       AST_DECLARE_STRING_FIELDS(
+               AST_STRING_FIELD(hostname);
+               AST_STRING_FIELD(dbname);
+               AST_STRING_FIELD(dbuser);
+               AST_STRING_FIELD(password);
+               AST_STRING_FIELD(table);
+               AST_STRING_FIELD(charset);
+               AST_STRING_FIELD(language);
+       );
+       TDSSOCKET *tds;
+       TDSLOGIN *login;
+       TDSCONTEXT *context;
+       unsigned int connected:1;
+       ast_mutex_t lock;
+};
 
-static TDSSOCKET *tds;
-static TDSLOGIN *login;
-static TDSCONTEXT *context;
+static struct cdr_tds_config *settings;
 
 static char *anti_injection(const char *, int);
 static void get_date(char *, struct timeval);
@@ -111,7 +119,7 @@ static int tds_log(struct ast_cdr *cdr)
        TDS_INT result_type;
 #endif
 
-       ast_mutex_lock(&tds_lock);
+       ast_mutex_lock(&settings->lock);
 
        memset(sqlcmd, 0, 2048);
 
@@ -172,7 +180,7 @@ static int tds_log(struct ast_cdr *cdr)
                        "'%s', "        /* amaflags */
                        "'%s'"          /* uniqueid */
                ")",
-               table,
+               settings->table,
                accountcode,
                src,
                dst,
@@ -193,7 +201,7 @@ static int tds_log(struct ast_cdr *cdr)
        );
 
        do {
-               if (!connected) {
+               if (!settings->connected) {
                        if (mssql_connect())
                                ast_log(LOG_ERROR, "Failed to reconnect to SQL database.\n");
                        else
@@ -203,16 +211,16 @@ static int tds_log(struct ast_cdr *cdr)
                }
 
 #ifdef FREETDS_PRE_0_62
-               if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
+               if (!settings->connected || (tds_submit_query(settings->tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(settings->tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
 #else
-               if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
+               if (!settings->connected || (tds_submit_query(settings->tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(settings->tds) != TDS_SUCCEED))
 #endif
                {
                        ast_log(LOG_ERROR, "Failed to insert Call Data Record into SQL database.\n");
 
                        mssql_disconnect();     /* this is ok even if we are already disconnected */
                }
-       } while (!connected && !retried);
+       } while (!settings->connected && !retried);
 
        ast_free(accountcode);
        ast_free(src);
@@ -225,7 +233,7 @@ static int tds_log(struct ast_cdr *cdr)
        ast_free(lastdata);
        ast_free(uniqueid);
 
-       ast_mutex_unlock(&tds_lock);
+       ast_mutex_unlock(&settings->lock);
 
        return res;
 }
@@ -233,14 +241,13 @@ static int tds_log(struct ast_cdr *cdr)
 static char *anti_injection(const char *str, int len)
 {
        /* Reference to http://www.nextgenss.com/papers/advanced_sql_injection.pdf */
-
        char *buf;
        char *buf_ptr, *srh_ptr;
        char *known_bad[] = {"select", "insert", "update", "delete", "drop", ";", "--", "\0"};
        int idx;
 
        if (!(buf = ast_calloc(1, len + 1))) {
-               ast_log(LOG_ERROR, "cdr_tds:  Out of memory error\n");
+               ast_log(LOG_ERROR, "Out of memory\n");
                return NULL;
        }
 
@@ -282,22 +289,22 @@ static void get_date(char *dateField, struct timeval tv)
 
 static int mssql_disconnect(void)
 {
-       if (tds) {
-               tds_free_socket(tds);
-               tds = NULL;
+       if (settings->tds) {
+               tds_free_socket(settings->tds);
+               settings->tds = NULL;
        }
 
-       if (context) {
-               tds_free_context(context);
-               context = NULL;
+       if (settings->context) {
+               tds_free_context(settings->context);
+               settings->context = NULL;
        }
 
-       if (login) {
-               tds_free_login(login);
-               login = NULL;
+       if (settings->login) {
+               tds_free_login(settings->login);
+               settings->login = NULL;
        }
 
-       connected = 0;
+       settings->connected = 0;
 
        return 0;
 }
@@ -312,48 +319,48 @@ static int mssql_connect(void)
        char query[128];
 
        /* Connect to M$SQL Server */
-       if (!(login = tds_alloc_login())) {
+       if (!(settings->login = tds_alloc_login())) {
                ast_log(LOG_ERROR, "tds_alloc_login() failed.\n");
                return -1;
        }
 
-       tds_set_server(login, hostname);
-       tds_set_user(login, dbuser);
-       tds_set_passwd(login, password);
-       tds_set_app(login, "TSQL");
-       tds_set_library(login, "TDS-Library");
+       tds_set_server(settings->login, settings->hostname);
+       tds_set_user(settings->login, settings->dbuser);
+       tds_set_passwd(settings->login, settings->password);
+       tds_set_app(settings->login, "TSQL");
+       tds_set_library(settings->login, "TDS-Library");
 #ifndef FREETDS_PRE_0_62
-       tds_set_client_charset(login, charset);
+       tds_set_client_charset(settings->login, settings->charset);
 #endif
-       tds_set_language(login, language);
-       tds_set_packet(login, 512);
-       tds_set_version(login, 7, 0);
+       tds_set_language(settings->login, settings->language);
+       tds_set_packet(settings->login, 512);
+       tds_set_version(settings->login, 7, 0);
 
 #ifdef FREETDS_0_64
-       if (!(context = tds_alloc_context(NULL)))
+       if (!(settings->context = tds_alloc_context(NULL)))
 #else
-       if (!(context = tds_alloc_context()))
+       if (!(settings->context = tds_alloc_context()))
 #endif
        {
                ast_log(LOG_ERROR, "tds_alloc_context() failed.\n");
                goto connect_fail;
        }
 
-       if (!(tds = tds_alloc_socket(context, 512))) {
+       if (!(settings->tds = tds_alloc_socket(settings->context, 512))) {
                ast_log(LOG_ERROR, "tds_alloc_socket() failed.\n");
                goto connect_fail;
        }
 
-       tds_set_parent(tds, NULL);
-       connection = tds_read_config_info(tds, login, context->locale);
+       tds_set_parent(settings->tds, NULL);
+       connection = tds_read_config_info(settings->tds, settings->login, settings->context->locale);
        if (!connection) {
                ast_log(LOG_ERROR, "tds_read_config() failed.\n");
                goto connect_fail;
        }
 
-       if (tds_connect(tds, connection) == TDS_FAIL) {
+       if (tds_connect(settings->tds, connection) == TDS_FAIL) {
                ast_log(LOG_ERROR, "Failed to connect to MSSQL server.\n");
-               tds = NULL;     /* freed by tds_connect() on error */
+               settings->tds = NULL;   /* freed by tds_connect() on error */
 #if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
                tds_free_connection(connection);
 #else
@@ -369,18 +376,18 @@ static int mssql_connect(void)
 #endif
        connection = NULL;
 
-       sprintf(query, "USE %s", dbname);
+       sprintf(query, "USE %s", settings->dbname);
 #ifdef FREETDS_PRE_0_62
-       if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
+       if ((tds_submit_query(settings->tds, query) != TDS_SUCCEED) || (tds_process_simple_query(settings->tds, &result_type) != TDS_SUCCEED || result_type != TDS_CMD_SUCCEED))
 #else
-       if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
+       if ((tds_submit_query(settings->tds, query) != TDS_SUCCEED) || (tds_process_simple_query(settings->tds) != TDS_SUCCEED))
 #endif
        {
-               ast_log(LOG_ERROR, "Could not change database (%s)\n", dbname);
+               ast_log(LOG_ERROR, "Could not change database (%s)\n", settings->dbname);
                goto connect_fail;
        }
 
-       connected = 1;
+       settings->connected = 1;
        return 0;
 
 connect_fail:
@@ -394,13 +401,9 @@ static int tds_unload_module(void)
 
        ast_cdr_unregister(name);
 
-       if (hostname) ast_free(hostname);
-       if (dbname) ast_free(dbname);
-       if (dbuser) ast_free(dbuser);
-       if (password) ast_free(password);
-       if (charset) ast_free(charset);
-       if (language) ast_free(language);
-       if (table) ast_free(table);
+       ast_mutex_destroy(&settings->lock);
+       ast_string_field_free_memory(settings);
+       ast_free(settings);
 
        return 0;
 }
@@ -425,69 +428,79 @@ static int tds_load_module(int reload)
                return 0;
        }
 
+       if (reload) {
+               ast_string_field_init(settings, 0);
+       } else {
+               settings = ast_calloc(1, sizeof(*settings));
+
+               if (!settings || ast_string_field_init(settings, 256)) {
+                       if (settings) {
+                               ast_free(settings);
+                               settings = NULL;
+                       }
+                       ast_config_destroy(cfg);
+                       return 0;
+               }
+       }
+
+       ast_mutex_init(&settings->lock);
+
        ptr = ast_variable_retrieve(cfg, "global", "hostname");
        if (ptr) {
-               if (hostname)
-                       ast_free(hostname);
-               hostname = ast_strdup(ptr);
-       } else
+               ast_string_field_set(settings, hostname, ptr);
+       } else {
                ast_log(LOG_ERROR, "Database server hostname not specified.\n");
+       }
 
        ptr = ast_variable_retrieve(cfg, "global", "dbname");
        if (ptr) {
-               if (dbname)
-                       ast_free(dbname);
-               dbname = ast_strdup(ptr);
-       } else
+               ast_string_field_set(settings, dbname, ptr);
+       } else {
                ast_log(LOG_ERROR, "Database dbname not specified.\n");
+       }
 
        ptr = ast_variable_retrieve(cfg, "global", "user");
        if (ptr) {
-               if (dbuser)
-                       ast_free(dbuser);
-               dbuser = ast_strdup(ptr);
-       } else
+               ast_string_field_set(settings, dbuser, ptr);
+       } else {
                ast_log(LOG_ERROR, "Database dbuser not specified.\n");
+       }
 
        ptr = ast_variable_retrieve(cfg, "global", "password");
        if (ptr) {
-               if (password)
-                       ast_free(password);
-               password = ast_strdup(ptr);
-       } else
+               ast_string_field_set(settings, password, ptr);
+       } else {
                ast_log(LOG_ERROR,"Database password not specified.\n");
+       }
 
        ptr = ast_variable_retrieve(cfg, "global", "charset");
-       if (charset)
-               ast_free(charset);
-       if (ptr)
-               charset = ast_strdup(ptr);
-       else
-               charset = ast_strdup("iso_1");
-
-       if (language)
-               ast_free(language);
+       if (ptr) {
+               ast_string_field_set(settings, charset, ptr);
+       } else {
+               ast_string_field_set(settings, charset, "iso_1");
+       }
+
        ptr = ast_variable_retrieve(cfg, "global", "language");
-       if (ptr)
-               language = ast_strdup(ptr);
-       else
-               language = ast_strdup("us_english");
+       if (ptr) {
+               ast_string_field_set(settings, language, ptr);
+       } else {
+               ast_string_field_set(settings, language, "us_english");
+       }
 
        ptr = ast_variable_retrieve(cfg, "global", "table");
-       if (ptr == NULL) {
-               ast_debug(1, "cdr_tds: table not specified.  Assuming cdr\n");
-               ptr = "cdr";
+       if (ptr) {
+               ast_string_field_set(settings, table, ptr);
+       } else {        
+               ast_debug(1, "Table not specified.  Assuming 'cdr'\n");
+               ast_string_field_set(settings, table, "cdr");
        }
-       if (table)
-               ast_free(table);
-       table = ast_strdup(ptr);
 
        ast_config_destroy(cfg);
 
-       ast_mutex_lock(&tds_lock);
+       ast_mutex_lock(&settings->lock);
        mssql_disconnect();
        mssql_connect();
-       ast_mutex_unlock(&tds_lock);
+       ast_mutex_unlock(&settings->lock);
 
        return 1;
 }