<p>Joshua Colp has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16289">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">cdr_mysql: Remove deprecated module.<br><br>ASTERISK-29584<br><br>Change-Id: I4bd3695d089121f810d692a82361d39d2f97ae39<br>---<br>M addons/Makefile<br>D addons/cdr_mysql.c<br>A doc/UPGRADE-staging/cdr_mysql_removal.txt<br>3 files changed, 6 insertions(+), 761 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/89/16289/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/addons/Makefile b/addons/Makefile</span><br><span>index 866d34b..02be9dc 100644</span><br><span>--- a/addons/Makefile</span><br><span>+++ b/addons/Makefile</span><br><span>@@ -29,7 +29,6 @@</span><br><span> H323CFLAGS:=-Iooh323c/src -Iooh323c/src/h323</span><br><span> </span><br><span> ALL_C_MODS:=app_mysql \</span><br><span style="color: hsl(0, 100%, 40%);">- cdr_mysql \</span><br><span> chan_mobile \</span><br><span> chan_ooh323 \</span><br><span> format_mp3 \</span><br><span>diff --git a/addons/cdr_mysql.c b/addons/cdr_mysql.c</span><br><span>deleted file mode 100644</span><br><span>index 25f8762..0000000</span><br><span>--- a/addons/cdr_mysql.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,760 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * James Sharp <jsharp@psychoses.org></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Modified August 2003</span><br><span style="color: hsl(0, 100%, 40%);">- * Tilghman Lesher <asterisk__cdr__cdr_mysql__200308@the-tilghman.com></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Modified August 6, 2005</span><br><span style="color: hsl(0, 100%, 40%);">- * Joseph Benden <joe@thrallingpenguin.com></span><br><span style="color: hsl(0, 100%, 40%);">- * Added mysql connection timeout parameter</span><br><span style="color: hsl(0, 100%, 40%);">- * Added an automatic reconnect as to not lose a cdr record</span><br><span style="color: hsl(0, 100%, 40%);">- * Cleaned up the original code to match the coding guidelines</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Modified Juli 2006</span><br><span style="color: hsl(0, 100%, 40%);">- * Martin Portmann <map@infinitum.ch></span><br><span style="color: hsl(0, 100%, 40%);">- * Added mysql ssl support</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(0, 100%, 40%);">- * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(0, 100%, 40%);">- * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(0, 100%, 40%);">- * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(0, 100%, 40%);">- * channels for your use.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software, distributed under the terms of</span><br><span style="color: hsl(0, 100%, 40%);">- * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(0, 100%, 40%);">- * at the top of the source tree.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*!</span><br><span style="color: hsl(0, 100%, 40%);">- * \file</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief MySQL CDR backend</span><br><span style="color: hsl(0, 100%, 40%);">- * \ingroup cdr_drivers</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*** MODULEINFO</span><br><span style="color: hsl(0, 100%, 40%);">- <depend>mysqlclient</depend></span><br><span style="color: hsl(0, 100%, 40%);">- <defaultenabled>no</defaultenabled></span><br><span style="color: hsl(0, 100%, 40%);">- <support_level>deprecated</support_level></span><br><span style="color: hsl(0, 100%, 40%);">- <replacement>cdr_adaptive_odbc</replacement></span><br><span style="color: hsl(0, 100%, 40%);">- <deprecated_in>1.8</deprecated_in></span><br><span style="color: hsl(0, 100%, 40%);">- <removed_in>19</removed_in></span><br><span style="color: hsl(0, 100%, 40%);">- ***/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <mysql/mysql.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <mysql/errmsg.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/config.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/options.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/channel.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/cdr.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/module.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/logger.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/cli.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/strings.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/linkedlists.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/threadstorage.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define DATE_FORMAT "%Y-%m-%d %T"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#ifndef MYSQL_PORT</span><br><span style="color: hsl(0, 100%, 40%);">-# ifdef MARIADB_PORT</span><br><span style="color: hsl(0, 100%, 40%);">-# define MYSQL_PORT MARIADB_PORT</span><br><span style="color: hsl(0, 100%, 40%);">-# else</span><br><span style="color: hsl(0, 100%, 40%);">-# define MYSQL_PORT 3306</span><br><span style="color: hsl(0, 100%, 40%);">-# endif</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_THREADSTORAGE(sql1_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-AST_THREADSTORAGE(sql2_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-AST_THREADSTORAGE(escape_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const char desc[] = "MySQL CDR Backend";</span><br><span style="color: hsl(0, 100%, 40%);">-static const char name[] = "mysql";</span><br><span style="color: hsl(0, 100%, 40%);">-static const char config[] = "cdr_mysql.conf";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_str *hostname = NULL, *dbname = NULL, *dbuser = NULL, *password = NULL, *dbsock = NULL, *dbtable = NULL, *dbcharset = NULL, *cdrzone = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_str *ssl_ca = NULL, *ssl_cert = NULL, *ssl_key = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int dbport = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static time_t connect_time = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int totalrecords = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int timeout = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-static int calldate_compat = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MUTEX_DEFINE_STATIC(mysql_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct unload_string {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_ENTRY(unload_string) entry;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str *str;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static AST_LIST_HEAD_STATIC(unload_strings, unload_string);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-struct column {</span><br><span style="color: hsl(0, 100%, 40%);">- char *name;</span><br><span style="color: hsl(0, 100%, 40%);">- char *cdrname;</span><br><span style="color: hsl(0, 100%, 40%);">- char *staticvalue;</span><br><span style="color: hsl(0, 100%, 40%);">- char *type;</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_ENTRY(column) list;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Protected with mysql_lock */</span><br><span style="color: hsl(0, 100%, 40%);">-static AST_RWLIST_HEAD_STATIC(columns, column);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static MYSQL mysql = { { NULL }, };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static char *handle_cli_cdr_mysql_status(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- switch (cmd) {</span><br><span style="color: hsl(0, 100%, 40%);">- case CLI_INIT:</span><br><span style="color: hsl(0, 100%, 40%);">- e->command = "cdr mysql status";</span><br><span style="color: hsl(0, 100%, 40%);">- e->usage =</span><br><span style="color: hsl(0, 100%, 40%);">- "Usage: cdr mysql status\n"</span><br><span style="color: hsl(0, 100%, 40%);">- " Shows current connection status for cdr_mysql\n";</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- case CLI_GENERATE:</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (a->argc != 3)</span><br><span style="color: hsl(0, 100%, 40%);">- return CLI_SHOWUSAGE;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (connected) {</span><br><span style="color: hsl(0, 100%, 40%);">- char status[256];</span><br><span style="color: hsl(0, 100%, 40%);">- char status2[100] = "";</span><br><span style="color: hsl(0, 100%, 40%);">- char buf[362]; /* 256+100+" for "+NULL */</span><br><span style="color: hsl(0, 100%, 40%);">- int ctime = time(NULL) - connect_time;</span><br><span style="color: hsl(0, 100%, 40%);">- if (dbport)</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(status, 255, "Connected to %s@%s, port %d", ast_str_buffer(dbname), ast_str_buffer(hostname), dbport);</span><br><span style="color: hsl(0, 100%, 40%);">- else if (dbsock)</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(status, 255, "Connected to %s on socket file %s", ast_str_buffer(dbname), S_OR(ast_str_buffer(dbsock), "default"));</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(status, 255, "Connected to %s@%s", ast_str_buffer(dbname), ast_str_buffer(hostname));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(dbuser))</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(status2, 99, " with username %s", ast_str_buffer(dbuser));</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(dbtable))</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(status2, 99, " using table %s", ast_str_buffer(dbtable));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(buf, sizeof(buf), "%s%s for ", status, status2);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cli_print_timestr_fromseconds(a->fd, ctime, buf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (records == totalrecords)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cli(a->fd, " Wrote %d records since last restart.\n", totalrecords);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cli(a->fd, " Wrote %d records since last restart and %d records since last reconnect.\n", totalrecords, records);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cli(a->fd, "Not currently connected to a MySQL server.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return CLI_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_cli_entry cdr_mysql_status_cli[] = {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_CLI_DEFINE(handle_cli_cdr_mysql_status, "Show connection status of cdr_mysql"),</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void configure_connection_charset(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(dbcharset)) {</span><br><span style="color: hsl(0, 100%, 40%);">- const char *charset = ast_str_buffer(dbcharset);</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, charset)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set connection charset. Data inserted might be invalid.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int mysql_log(struct ast_cdr *cdr)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str *sql1 = ast_str_thread_get(&sql1_buf, 1024), *sql2 = ast_str_thread_get(&sql2_buf, 1024);</span><br><span style="color: hsl(0, 100%, 40%);">- int retries = 5;</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef HAVE_MYSQLCLIENT_BOOL</span><br><span style="color: hsl(0, 100%, 40%);">- bool my_bool_true = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-#elif HAVE_MYSQLCLIENT_MY_BOOL</span><br><span style="color: hsl(0, 100%, 40%);">- my_bool my_bool_true = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!sql1 || !sql2) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Memory error\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_lock(&mysql_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-db_reconnect:</span><br><span style="color: hsl(0, 100%, 40%);">- if ((!connected) && (hostname || dbsock) && dbuser && password && dbname && dbtable ) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Attempt to connect */</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_init(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Add option to quickly timeout the connection */</span><br><span style="color: hsl(0, 100%, 40%);">- if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#if MYSQL_VERSION_ID >= 50013</span><br><span style="color: hsl(0, 100%, 40%);">- /* Add option for automatic reconnection */</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- if (ssl_ca || ssl_cert || ssl_key) {</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_ssl_set(&mysql, ssl_key ? ast_str_buffer(ssl_key) : NULL, ssl_cert ? ast_str_buffer(ssl_cert) : NULL, ssl_ca ? ast_str_buffer(ssl_ca) : NULL, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- configure_connection_charset();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_real_connect(&mysql, ast_str_buffer(hostname), ast_str_buffer(dbuser), ast_str_buffer(password), ast_str_buffer(dbname), dbport, dbsock && ast_str_strlen(dbsock) ? ast_str_buffer(dbsock) : NULL, ssl_ca ? CLIENT_SSL : 0)) {</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- connect_time = time(NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Cannot connect to database server %s: (%d) %s\n", ast_str_buffer(hostname), mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Long connection - ping the server */</span><br><span style="color: hsl(0, 100%, 40%);">- int error;</span><br><span style="color: hsl(0, 100%, 40%);">- if ((error = mysql_ping(&mysql))) {</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- switch (mysql_errno(&mysql)) {</span><br><span style="color: hsl(0, 100%, 40%);">- case CR_SERVER_GONE_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">- case CR_SERVER_LOST:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Server has gone away. Attempting to reconnect.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unknown connection error: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- retries--;</span><br><span style="color: hsl(0, 100%, 40%);">- if (retries) {</span><br><span style="color: hsl(0, 100%, 40%);">- goto db_reconnect;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Retried to connect five times, giving up.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (connected) {</span><br><span style="color: hsl(0, 100%, 40%);">- int column_count = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- char *cdrname;</span><br><span style="color: hsl(0, 100%, 40%);">- char workspace[2048], *value = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct column *entry;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str *escape = ast_str_thread_get(&escape_buf, 16);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&sql1, 0, "INSERT INTO %s (", AS_OR(dbtable, "cdr"));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&sql2, 0, ") VALUES (");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_RDLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_TRAVERSE(&columns, entry, list) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcmp(entry->name, "calldate")) {</span><br><span style="color: hsl(0, 100%, 40%);">- /*!\note</span><br><span style="color: hsl(0, 100%, 40%);">- * For some dumb reason, "calldate" used to be formulated using</span><br><span style="color: hsl(0, 100%, 40%);">- * the datetime the record was posted, rather than the start</span><br><span style="color: hsl(0, 100%, 40%);">- * time of the call. If someone really wants the old compatible</span><br><span style="color: hsl(0, 100%, 40%);">- * behavior, it's provided here.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- if (calldate_compat) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct timeval tv = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_tm tm;</span><br><span style="color: hsl(0, 100%, 40%);">- char timestr[128];</span><br><span style="color: hsl(0, 100%, 40%);">- ast_localtime(&tv, &tm, ast_str_strlen(cdrzone) ? ast_str_buffer(cdrzone) : NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);</span><br><span style="color: hsl(0, 100%, 40%);">- value = ast_strdupa(timestr);</span><br><span style="color: hsl(0, 100%, 40%);">- cdrname = "calldate";</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- cdrname = "start";</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- cdrname = entry->cdrname;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Construct SQL */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Need the type and value to determine if we want the raw value or not */</span><br><span style="color: hsl(0, 100%, 40%);">- if (entry->staticvalue) {</span><br><span style="color: hsl(0, 100%, 40%);">- value = ast_strdupa(entry->staticvalue);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if ((!strcmp(cdrname, "disposition") ||</span><br><span style="color: hsl(0, 100%, 40%);">- !strcmp(cdrname, "amaflags")) &&</span><br><span style="color: hsl(0, 100%, 40%);">- (strstr(entry->type, "int") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "dec") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "float") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "double") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "real") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "numeric") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "fixed"))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cdr_format_var(cdr, cdrname, &value, workspace, sizeof(workspace), 1);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcmp(cdrname, "start") || !strcmp(cdrname, "answer") ||</span><br><span style="color: hsl(0, 100%, 40%);">- !strcmp(cdrname, "end")) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_tm tm;</span><br><span style="color: hsl(0, 100%, 40%);">- char timestr[128];</span><br><span style="color: hsl(0, 100%, 40%);">- ast_localtime(&cdr->start, &tm, ast_str_strlen(cdrzone) ? ast_str_buffer(cdrzone) : NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);</span><br><span style="color: hsl(0, 100%, 40%);">- value = ast_strdupa(timestr);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcmp(cdrname, "calldate")) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Skip calldate - the value has already been dup'd */</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cdr_format_var(cdr, cdrname, &value, workspace, sizeof(workspace), 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (value) {</span><br><span style="color: hsl(0, 100%, 40%);">- size_t valsz;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (column_count++) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&sql1, 0, ",");</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&sql2, 0, ",");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(cdrname, "billsec") &&</span><br><span style="color: hsl(0, 100%, 40%);">- (strstr(entry->type, "float") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "double") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "decimal") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "numeric") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "real"))) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_tvzero(cdr->answer)) {</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(workspace, sizeof(workspace), "%lf",</span><br><span style="color: hsl(0, 100%, 40%);">- (double) (ast_tvdiff_us(cdr->end, cdr->answer) / 1000000.0));</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(workspace, "0", sizeof(workspace));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(workspace)) {</span><br><span style="color: hsl(0, 100%, 40%);">- value = workspace;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(cdrname, "duration") &&</span><br><span style="color: hsl(0, 100%, 40%);">- (strstr(entry->type, "float") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "double") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "decimal") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "numeric") ||</span><br><span style="color: hsl(0, 100%, 40%);">- strstr(entry->type, "real"))) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(workspace, sizeof(workspace), "%lf",</span><br><span style="color: hsl(0, 100%, 40%);">- (double) (ast_tvdiff_us(cdr->end, cdr->start) / 1000000.0));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(workspace)) {</span><br><span style="color: hsl(0, 100%, 40%);">- value = workspace;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_make_space(&escape, (valsz = strlen(value)) * 2 + 1);</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_real_escape_string(&mysql, ast_str_buffer(escape), value, valsz);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&sql1, 0, "`%s`", entry->name);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&sql2, 0, "'%s'", ast_str_buffer(escape));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_UNLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Inserting a CDR record.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_append(&sql1, 0, "%s)", ast_str_buffer(sql2));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "SQL command as follows: %s\n", ast_str_buffer(sql1));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_real_query(&mysql, ast_str_buffer(sql1), ast_str_strlen(sql1))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Failed to insert into database: (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_close(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- records++;</span><br><span style="color: hsl(0, 100%, 40%);">- totalrecords++;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&mysql_lock);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void free_strings(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct unload_string *us;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_LOCK(&unload_strings);</span><br><span style="color: hsl(0, 100%, 40%);">- while ((us = AST_LIST_REMOVE_HEAD(&unload_strings, entry))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(us->str);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(us);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_UNLOCK(&unload_strings);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int my_unload_module(int reload)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct column *entry;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_cdr_unregister(name)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we can't unregister the backend, we can't unload the module */</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_cli_unregister_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (connected) {</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_close(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- free_strings();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_WRLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- while ((entry = AST_RWLIST_REMOVE_HEAD(&columns, list))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(entry);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (!reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_UNLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- dbport = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- if (reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- return ast_cdr_backend_suspend(name);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- /* We unregistered earlier */</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int my_load_config_string(struct ast_config *cfg, const char *category, const char *variable, struct ast_str **field, const char *def)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct unload_string *us;</span><br><span style="color: hsl(0, 100%, 40%);">- const char *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(us = ast_calloc(1, sizeof(*us))))</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(*field = ast_str_create(16))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(us);</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = ast_variable_retrieve(cfg, category, variable);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(field, 0, "%s", tmp ? tmp : def);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- us->str = *field;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_LOCK(&unload_strings);</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_INSERT_HEAD(&unload_strings, us, entry);</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_UNLOCK(&unload_strings);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int my_load_config_number(struct ast_config *cfg, const char *category, const char *variable, int *field, int def)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- const char *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = ast_variable_retrieve(cfg, category, variable);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!tmp || sscanf(tmp, "%30d", field) < 1)</span><br><span style="color: hsl(0, 100%, 40%);">- *field = def;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/** Connect to MySQL. Initializes the connection.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * * Assumes the read-write lock for columns is held.</span><br><span style="color: hsl(0, 100%, 40%);">- * * Caller should allocate and free cfg</span><br><span style="color: hsl(0, 100%, 40%);">- * */</span><br><span style="color: hsl(0, 100%, 40%);">-static int my_connect_db(struct ast_config *cfg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_variable *var;</span><br><span style="color: hsl(0, 100%, 40%);">- char *temp;</span><br><span style="color: hsl(0, 100%, 40%);">- MYSQL_ROW row;</span><br><span style="color: hsl(0, 100%, 40%);">- MYSQL_RES *result;</span><br><span style="color: hsl(0, 100%, 40%);">- char sqldesc[128];</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef HAVE_MYSQLCLIENT_BOOL</span><br><span style="color: hsl(0, 100%, 40%);">- bool my_bool_true = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-#elif HAVE_MYSQLCLIENT_MY_BOOL</span><br><span style="color: hsl(0, 100%, 40%);">- my_bool my_bool_true = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_init(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (timeout && mysql_options(&mysql, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if MYSQL_VERSION_ID >= 50013</span><br><span style="color: hsl(0, 100%, 40%);">- /* Add option for automatic reconnection */</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_options(&mysql, MYSQL_OPT_RECONNECT, &my_bool_true) != 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "cdr_mysql: mysql_options returned (%d) %s\n", mysql_errno(&mysql), mysql_error(&mysql));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((ssl_ca && ast_str_strlen(ssl_ca)) || (ssl_cert && ast_str_strlen(ssl_cert)) || (ssl_key && ast_str_strlen(ssl_key))) {</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_ssl_set(&mysql,</span><br><span style="color: hsl(0, 100%, 40%);">- ssl_key ? ast_str_buffer(ssl_key) : NULL,</span><br><span style="color: hsl(0, 100%, 40%);">- ssl_cert ? ast_str_buffer(ssl_cert) : NULL,</span><br><span style="color: hsl(0, 100%, 40%);">- ssl_ca ? ast_str_buffer(ssl_ca) : NULL,</span><br><span style="color: hsl(0, 100%, 40%);">- NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- temp = dbsock && ast_str_strlen(dbsock) ? ast_str_buffer(dbsock) : NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- configure_connection_charset();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!mysql_real_connect(&mysql, ast_str_buffer(hostname), ast_str_buffer(dbuser), ast_str_buffer(password), ast_str_buffer(dbname), dbport, temp, ssl_ca && ast_str_strlen(ssl_ca) ? CLIENT_SSL : 0)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Failed to connect to mysql database %s on %s.\n", ast_str_buffer(dbname), ast_str_buffer(hostname));</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS; /* May be reconnected later */</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Successfully connected to MySQL database.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- records = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- connect_time = time(NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Get table description */</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(sqldesc, sizeof(sqldesc), "DESC %s", dbtable ? ast_str_buffer(dbtable) : "cdr");</span><br><span style="color: hsl(0, 100%, 40%);">- if (mysql_query(&mysql, sqldesc)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_close(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(result = mysql_store_result(&mysql))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to query table description!! Logging disabled.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_close(&mysql);</span><br><span style="color: hsl(0, 100%, 40%);">- connected = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- while ((row = mysql_fetch_row(result))) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct column *entry;</span><br><span style="color: hsl(0, 100%, 40%);">- char *cdrvar = "", *staticvalue = "";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got a field '%s' of type '%s'\n", row[0], row[1]);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Check for an alias or a static value */</span><br><span style="color: hsl(0, 100%, 40%);">- for (var = ast_variable_browse(cfg, "columns"); var; var = var->next) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (strncmp(var->name, "alias", 5) == 0 && strcasecmp(var->value, row[0]) == 0 ) {</span><br><span style="color: hsl(0, 100%, 40%);">- char *alias = ast_strdupa(var->name + 5);</span><br><span style="color: hsl(0, 100%, 40%);">- cdrvar = ast_strip(alias);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verb(3, "Found alias %s for column %s\n", cdrvar, row[0]);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (strncmp(var->name, "static", 6) == 0 && strcasecmp(var->value, row[0]) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- char *item = ast_strdupa(var->name + 6);</span><br><span style="color: hsl(0, 100%, 40%);">- item = ast_strip(item);</span><br><span style="color: hsl(0, 100%, 40%);">- if (item[0] == '"' && item[strlen(item) - 1] == '"') {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Remove surrounding quotes */</span><br><span style="color: hsl(0, 100%, 40%);">- item[strlen(item) - 1] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">- item++;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- staticvalue = item;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(row[0]) + 1 + strlen(cdrvar) + 1 + strlen(staticvalue) + 1 + strlen(row[1]) + 1);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!entry) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Out of memory creating entry for column '%s'\n", row[0]);</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_free_result(result);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- entry->name = (char *)entry + sizeof(*entry);</span><br><span style="color: hsl(0, 100%, 40%);">- strcpy(entry->name, row[0]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(cdrvar)) {</span><br><span style="color: hsl(0, 100%, 40%);">- entry->cdrname = entry->name + strlen(row[0]) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">- strcpy(entry->cdrname, cdrvar);</span><br><span style="color: hsl(0, 100%, 40%);">- } else { /* Point to same place as the column name */</span><br><span style="color: hsl(0, 100%, 40%);">- entry->cdrname = (char *)entry + sizeof(*entry);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(staticvalue)) {</span><br><span style="color: hsl(0, 100%, 40%);">- entry->staticvalue = entry->cdrname + strlen(entry->cdrname) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">- strcpy(entry->staticvalue, staticvalue);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "staticvalue length: %d\n", (int) strlen(staticvalue) );</span><br><span style="color: hsl(0, 100%, 40%);">- entry->type = entry->staticvalue + strlen(entry->staticvalue) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- entry->type = entry->cdrname + strlen(entry->cdrname) + 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- strcpy(entry->type, row[1]);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Entry name '%s'\n", entry->name);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, " cdrname '%s'\n", entry->cdrname);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, " static '%s'\n", entry->staticvalue);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, " type '%s'\n", entry->type);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- AST_LIST_INSERT_TAIL(&columns, entry, list);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- mysql_free_result(result);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int my_load_module(int reload)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_config *cfg;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_variable *var;</span><br><span style="color: hsl(0, 100%, 40%);">- /* CONFIG_STATUS_FILEUNCHANGED is impossible when config_flags is always 0,</span><br><span style="color: hsl(0, 100%, 40%);">- * and it has to be zero, so a reload can be sent to tell the driver to</span><br><span style="color: hsl(0, 100%, 40%);">- * rescan the table layout. */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_flags config_flags = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">- struct column *entry;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str *compat;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Cannot use a conditionally different flag, because the table layout may</span><br><span style="color: hsl(0, 100%, 40%);">- * have changed, which is not detectable by config file change detection,</span><br><span style="color: hsl(0, 100%, 40%);">- * but should still cause the configuration to be re-parsed. */</span><br><span style="color: hsl(0, 100%, 40%);">- cfg = ast_config_load(config, config_flags);</span><br><span style="color: hsl(0, 100%, 40%);">- if (cfg == CONFIG_STATUS_FILEMISSING) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to load config for mysql CDR's: %s\n", config);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (cfg == CONFIG_STATUS_FILEINVALID) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to load configuration file '%s'\n", config);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_WRLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- my_unload_module(1);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- var = ast_variable_browse(cfg, "global");</span><br><span style="color: hsl(0, 100%, 40%);">- if (!var) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* nothing configured */</span><br><span style="color: hsl(0, 100%, 40%);">- if (reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_UNLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "hostname", &hostname, "localhost");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "dbname", &dbname, "astriskcdrdb");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "user", &dbuser, "root");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "sock", &dbsock, "");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "table", &dbtable, "cdr");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "password", &password, "");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "charset", &dbcharset, "");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "ssl_ca", &ssl_ca, "");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "ssl_cert", &ssl_cert, "");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "ssl_key", &ssl_key, "");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_number(cfg, "global", "port", &dbport, MYSQL_PORT);</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_number(cfg, "global", "timeout", &timeout, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "compat", &compat, "no");</span><br><span style="color: hsl(0, 100%, 40%);">- res |= my_load_config_string(cfg, "global", "cdrzone", &cdrzone, "");</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(cdrzone) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- for (; var; var = var->next) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(var->name, "usegmtime") && ast_true(var->value)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_str_set(&cdrzone, 0, "UTC");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_true(ast_str_buffer(compat))) {</span><br><span style="color: hsl(0, 100%, 40%);">- calldate_compat = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- calldate_compat = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_UNLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- free_strings();</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Check for any aliases */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Lock, if not already */</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_WRLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- while ((entry = AST_LIST_REMOVE_HEAD(&columns, list))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(entry);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got hostname of %s\n", ast_str_buffer(hostname));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got port of %d\n", dbport);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got a timeout of %d\n", timeout);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(dbsock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got sock file of %s\n", ast_str_buffer(dbsock));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got user of %s\n", ast_str_buffer(dbuser));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got dbname of %s\n", ast_str_buffer(dbname));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got password of %s\n", ast_str_buffer(password));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "%sunning in calldate compatibility mode\n", calldate_compat ? "R" : "Not r");</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Dates and times are localized to %s\n", S_OR(ast_str_buffer(cdrzone), "local timezone"));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_str_strlen(dbcharset)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got DB charset of %s\n", ast_str_buffer(dbcharset));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- res = my_connect_db(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- AST_RWLIST_UNLOCK(&columns);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- if (res != AST_MODULE_LOAD_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">- my_unload_module(0);</span><br><span style="color: hsl(0, 100%, 40%);">- return res;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!reload) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_cdr_register(name, desc, mysql_log);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_cdr_backend_unsuspend(name);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (res) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to register MySQL CDR handling\n");</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_cli_register_multiple(cdr_mysql_status_cli, sizeof(cdr_mysql_status_cli) / sizeof(struct ast_cli_entry));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (res) {</span><br><span style="color: hsl(0, 100%, 40%);">- my_unload_module(0);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int load_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return my_load_module(0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int unload_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return my_unload_module(0);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int reload(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int ret;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_lock(&mysql_lock);</span><br><span style="color: hsl(0, 100%, 40%);">- ret = my_load_module(1);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&mysql_lock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return ret;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "MySQL CDR Backend",</span><br><span style="color: hsl(0, 100%, 40%);">- .support_level = AST_MODULE_SUPPORT_DEPRECATED,</span><br><span style="color: hsl(0, 100%, 40%);">- .load = load_module,</span><br><span style="color: hsl(0, 100%, 40%);">- .unload = unload_module,</span><br><span style="color: hsl(0, 100%, 40%);">- .reload = reload,</span><br><span style="color: hsl(0, 100%, 40%);">- .requires = "cdr",</span><br><span style="color: hsl(0, 100%, 40%);">-);</span><br><span>diff --git a/doc/UPGRADE-staging/cdr_mysql_removal.txt b/doc/UPGRADE-staging/cdr_mysql_removal.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..a90690e</span><br><span>--- /dev/null</span><br><span>+++ b/doc/UPGRADE-staging/cdr_mysql_removal.txt</span><br><span>@@ -0,0 +1,6 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: cdr_mysql</span><br><span style="color: hsl(120, 100%, 40%);">+Master-Only: True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This module was deprecated in Asterisk 1.8</span><br><span style="color: hsl(120, 100%, 40%);">+and is now being removed in accordance with</span><br><span style="color: hsl(120, 100%, 40%);">+the Asterisk Module Deprecation policy.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16289">change 16289</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16289"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: I4bd3695d089121f810d692a82361d39d2f97ae39 </div>
<div style="display:none"> Gerrit-Change-Number: 16289 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>