aboutsummaryrefslogtreecommitdiffstats
path: root/cdr
diff options
context:
space:
mode:
Diffstat (limited to 'cdr')
-rw-r--r--cdr/Makefile32
-rw-r--r--cdr/cdr_csv.c365
-rw-r--r--cdr/cdr_custom.c174
-rw-r--r--cdr/cdr_manager.c170
-rw-r--r--cdr/cdr_odbc.c481
-rw-r--r--cdr/cdr_pgsql.c336
-rw-r--r--cdr/cdr_radius.c273
-rw-r--r--cdr/cdr_sqlite.c217
-rw-r--r--cdr/cdr_tds.c630
9 files changed, 0 insertions, 2678 deletions
diff --git a/cdr/Makefile b/cdr/Makefile
deleted file mode 100644
index b7e854468..000000000
--- a/cdr/Makefile
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Asterisk -- A telephony toolkit for Linux.
-#
-# Makefile for CDR backends
-#
-# Copyright (C) 1999-2006, Digium, Inc.
-#
-# This program is free software, distributed under the terms of
-# the GNU General Public License
-#
-
--include ../menuselect.makeopts ../menuselect.makedeps
-
-MENUSELECT_CATEGORY=CDR
-MENUSELECT_DESCRIPTION=Call Detail Recording
-
-ALL_C_MODS:=$(patsubst %.c,%,$(wildcard cdr_*.c))
-ALL_CC_MODS:=$(patsubst %.cc,%,$(wildcard cdr_*.cc))
-
-C_MODS:=$(filter-out $(MENUSELECT_CDR),$(ALL_C_MODS))
-CC_MODS:=$(filter-out $(MENUSELECT_CDR),$(ALL_CC_MODS))
-
-LOADABLE_MODS:=$(C_MODS) $(CC_MODS)
-
-ifneq ($(findstring cdr,$(MENUSELECT_EMBED)),)
- EMBEDDED_MODS:=$(LOADABLE_MODS)
- LOADABLE_MODS:=
-endif
-
-all: _all
-
-include $(ASTTOPDIR)/Makefile.moddir_rules
diff --git a/cdr/cdr_csv.c b/cdr/cdr_csv.c
deleted file mode 100644
index cdaef6853..000000000
--- a/cdr/cdr_csv.c
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Comma Separated Value CDR records.
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also \ref AstCDR
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/config.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-#define CSV_LOG_DIR "/cdr-csv"
-#define CSV_MASTER "/Master.csv"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static int usegmtime = 0;
-static int loguniqueid = 0;
-static int loguserfield = 0;
-static int loaded = 0;
-static char *config = "cdr.conf";
-
-/* #define CSV_LOGUNIQUEID 1 */
-/* #define CSV_LOGUSERFIELD 1 */
-
-/*----------------------------------------------------
- The values are as follows:
-
-
- "accountcode", accountcode is the account name of detail records, Master.csv contains all records *
- Detail records are configured on a channel basis, IAX and SIP are determined by user *
- DAHDI is determined by channel in chan_dahdi.conf
- "source",
- "destination",
- "destination context",
- "callerid",
- "channel",
- "destination channel", (if applicable)
- "last application", Last application run on the channel
- "last app argument", argument to the last channel
- "start time",
- "answer time",
- "end time",
- duration, Duration is the whole length that the entire call lasted. ie. call rx'd to hangup
- "end time" minus "start time"
- billable seconds, the duration that a call was up after other end answered which will be <= to duration
- "end time" minus "answer time"
- "disposition", ANSWERED, NO ANSWER, BUSY
- "amaflags", DOCUMENTATION, BILL, IGNORE etc, specified on a per channel basis like accountcode.
- "uniqueid", unique call identifier
- "userfield" user field set via SetCDRUserField
-----------------------------------------------------------*/
-
-static char *name = "csv";
-
-AST_MUTEX_DEFINE_STATIC(mf_lock);
-AST_MUTEX_DEFINE_STATIC(acf_lock);
-
-static int load_config(void)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *tmp;
-
- usegmtime = 0;
- loguniqueid = 0;
- loguserfield = 0;
-
- cfg = ast_config_load(config);
-
- if (!cfg) {
- ast_log(LOG_WARNING, "unable to load config: %s\n", config);
- return 0;
- }
-
- var = ast_variable_browse(cfg, "csv");
- if (!var) {
- ast_config_destroy(cfg);
- return 0;
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "usegmtime");
- if (tmp) {
- usegmtime = ast_true(tmp);
- if (usegmtime) {
- ast_log(LOG_DEBUG, "logging time in GMT\n");
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "loguniqueid");
- if (tmp) {
- loguniqueid = ast_true(tmp);
- if (loguniqueid) {
- ast_log(LOG_DEBUG, "logging CDR field UNIQUEID\n");
- }
- }
-
- tmp = ast_variable_retrieve(cfg, "csv", "loguserfield");
- if (tmp) {
- loguserfield = ast_true(tmp);
- if (loguserfield) {
- ast_log(LOG_DEBUG, "logging CDR user-defined field\n");
- }
- }
-
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int append_string(char *buf, char *s, size_t bufsize)
-{
- int pos = strlen(buf);
- int spos = 0;
- int error = 0;
- if (pos >= bufsize - 4)
- return -1;
- buf[pos++] = '\"';
- error = -1;
- while(pos < bufsize - 3) {
- if (!s[spos]) {
- error = 0;
- break;
- }
- if (s[spos] == '\"')
- buf[pos++] = '\"';
- buf[pos++] = s[spos];
- spos++;
- }
- buf[pos++] = '\"';
- buf[pos++] = ',';
- buf[pos++] = '\0';
- return error;
-}
-
-static int append_int(char *buf, int s, size_t bufsize)
-{
- char tmp[32];
- int pos = strlen(buf);
- snprintf(tmp, sizeof(tmp), "%d", s);
- if (pos + strlen(tmp) > bufsize - 3)
- return -1;
- strncat(buf, tmp, bufsize - strlen(buf) - 1);
- pos = strlen(buf);
- buf[pos++] = ',';
- buf[pos++] = '\0';
- return 0;
-}
-
-static int append_date(char *buf, struct timeval tv, size_t bufsize)
-{
- char tmp[80] = "";
- struct tm tm;
- time_t t;
- t = tv.tv_sec;
- if (strlen(buf) > bufsize - 3)
- return -1;
- if (ast_tvzero(tv)) {
- strncat(buf, ",", bufsize - strlen(buf) - 1);
- return 0;
- }
- if (usegmtime) {
- gmtime_r(&t,&tm);
- } else {
- ast_localtime(&t, &tm, NULL);
- }
- strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
- return append_string(buf, tmp, bufsize);
-}
-
-static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
-{
-
- buf[0] = '\0';
- /* Account code */
- append_string(buf, cdr->accountcode, bufsize);
- /* Source */
- append_string(buf, cdr->src, bufsize);
- /* Destination */
- append_string(buf, cdr->dst, bufsize);
- /* Destination context */
- append_string(buf, cdr->dcontext, bufsize);
- /* Caller*ID */
- append_string(buf, cdr->clid, bufsize);
- /* Channel */
- append_string(buf, cdr->channel, bufsize);
- /* Destination Channel */
- append_string(buf, cdr->dstchannel, bufsize);
- /* Last Application */
- append_string(buf, cdr->lastapp, bufsize);
- /* Last Data */
- append_string(buf, cdr->lastdata, bufsize);
- /* Start Time */
- append_date(buf, cdr->start, bufsize);
- /* Answer Time */
- append_date(buf, cdr->answer, bufsize);
- /* End Time */
- append_date(buf, cdr->end, bufsize);
- /* Duration */
- append_int(buf, cdr->duration, bufsize);
- /* Billable seconds */
- append_int(buf, cdr->billsec, bufsize);
- /* Disposition */
- append_string(buf, ast_cdr_disp2str(cdr->disposition), bufsize);
- /* AMA Flags */
- append_string(buf, ast_cdr_flags2str(cdr->amaflags), bufsize);
- /* Unique ID */
- if (loguniqueid)
- append_string(buf, cdr->uniqueid, bufsize);
- /* append the user field */
- if(loguserfield)
- append_string(buf, cdr->userfield,bufsize);
- /* If we hit the end of our buffer, log an error */
- if (strlen(buf) < bufsize - 5) {
- /* Trim off trailing comma */
- buf[strlen(buf) - 1] = '\0';
- strncat(buf, "\n", bufsize - strlen(buf) - 1);
- return 0;
- }
- return -1;
-}
-
-static int writefile(char *s, char *acc)
-{
- char tmp[PATH_MAX];
- FILE *f;
- if (strchr(acc, '/') || (acc[0] == '.')) {
- ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
- return -1;
- }
- snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", (char *)ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
-
- ast_mutex_lock(&acf_lock);
- f = fopen(tmp, "a");
- if (!f) {
- ast_mutex_unlock(&acf_lock);
- ast_log(LOG_ERROR, "Unable to open file %s : %s\n", tmp, strerror(errno));
- return -1;
- }
- fputs(s, f);
- fflush(f);
- fclose(f);
- ast_mutex_unlock(&acf_lock);
-
- return 0;
-}
-
-
-static int csv_log(struct ast_cdr *cdr)
-{
- FILE *mf = NULL;
- /* Make sure we have a big enough buf */
- char buf[1024];
- char csvmaster[PATH_MAX];
- snprintf(csvmaster, sizeof(csvmaster),"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER);
-#if 0
- printf("[CDR] %s ('%s' -> '%s') Dur: %ds Bill: %ds Disp: %s Flags: %s Account: [%s]\n", cdr->channel, cdr->src, cdr->dst, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->accountcode);
-#endif
- if (build_csv_record(buf, sizeof(buf), cdr)) {
- ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes. CDR not recorded!\n", (int)sizeof(buf));
- } else {
- /* because of the absolutely unconditional need for the
- highest reliability possible in writing billing records,
- we open write and close the log file each time */
- ast_mutex_lock(&mf_lock);
- mf = fopen(csvmaster, "a");
- if (mf) {
- fputs(buf, mf);
- fflush(mf); /* be particularly anal here */
- fclose(mf);
- mf = NULL;
- ast_mutex_unlock(&mf_lock);
- } else {
- ast_mutex_unlock(&mf_lock);
- ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", csvmaster, strerror(errno));
- }
-
- if (!ast_strlen_zero(cdr->accountcode)) {
- if (writefile(buf, cdr->accountcode))
- ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno));
- }
- }
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- loaded = 0;
- return 0;
-}
-
-static int load_module(void)
-{
- int res;
-
- if(!load_config())
- return AST_MODULE_LOAD_DECLINE;
-
- res = ast_cdr_register(name, ast_module_info->description, csv_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
- } else {
- loaded = 1;
- }
- return res;
-}
-
-static int reload(void)
-{
- if (load_config()) {
- loaded = 1;
- } else {
- loaded = 0;
- ast_log(LOG_WARNING, "No [csv] section in cdr.conf. Unregistering backend.\n");
- ast_cdr_unregister(name);
- }
-
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Comma Separated Values CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/cdr/cdr_custom.c b/cdr/cdr_custom.c
deleted file mode 100644
index c390b0499..000000000
--- a/cdr/cdr_custom.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * Includes code and algorithms from the Zapata library.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Custom Comma Separated Value CDR records.
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also \ref AstCDR
- *
- * Logs in LOG_DIR/cdr_custom
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/config.h"
-#include "asterisk/pbx.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-
-#define CUSTOM_LOG_DIR "/cdr_custom"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-AST_MUTEX_DEFINE_STATIC(lock);
-AST_MUTEX_DEFINE_STATIC(mf_lock);
-
-static char *name = "cdr-custom";
-
-static char master[PATH_MAX];
-static char format[1024]="";
-
-static int load_config(int reload)
-{
- struct ast_config *cfg;
- struct ast_variable *var;
- int res = -1;
-
- strcpy(format, "");
- strcpy(master, "");
- ast_mutex_lock(&lock);
- if((cfg = ast_config_load("cdr_custom.conf"))) {
- var = ast_variable_browse(cfg, "mappings");
- while(var) {
- if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
- if (strlen(var->value) > (sizeof(format) - 1))
- ast_log(LOG_WARNING, "Format string too long, will be truncated, at line %d\n", var->lineno);
- ast_copy_string(format, var->value, sizeof(format) - 1);
- strcat(format,"\n");
- snprintf(master, sizeof(master),"%s/%s/%s", ast_config_AST_LOG_DIR, name, var->name);
- if (var->next) {
- ast_log(LOG_NOTICE, "Sorry, only one mapping is supported at this time, mapping '%s' will be ignored at line %d.\n", var->next->name, var->next->lineno);
- break;
- }
- } else
- ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
- var = var->next;
- }
- ast_config_destroy(cfg);
- res = 0;
- } else {
- if (reload)
- ast_log(LOG_WARNING, "Failed to reload configuration file.\n");
- else
- ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
- }
- ast_mutex_unlock(&lock);
-
- return res;
-}
-
-
-
-static int custom_log(struct ast_cdr *cdr)
-{
- FILE *mf = NULL;
-
- /* Make sure we have a big enough buf */
- char buf[2048];
- struct ast_channel dummy;
-
- /* Abort if no master file is specified */
- if (ast_strlen_zero(master))
- return 0;
-
- memset(buf, 0 , sizeof(buf));
- /* Quite possibly the first use of a static struct ast_channel, we need it so the var funcs will work */
- memset(&dummy, 0, sizeof(dummy));
- dummy.cdr = cdr;
- pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);
-
- /* because of the absolutely unconditional need for the
- highest reliability possible in writing billing records,
- we open write and close the log file each time */
- ast_mutex_lock(&mf_lock);
- mf = fopen(master, "a");
- if (mf) {
- fputs(buf, mf);
- fflush(mf); /* be particularly anal here */
- fclose(mf);
- mf = NULL;
- ast_mutex_unlock(&mf_lock);
- } else {
- ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
- ast_mutex_unlock(&mf_lock);
- }
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- int res = 0;
-
- if (!load_config(0)) {
- res = ast_cdr_register(name, ast_module_info->description, custom_log);
- if (res)
- ast_log(LOG_ERROR, "Unable to register custom CDR handling\n");
- return res;
- } else
- return AST_MODULE_LOAD_DECLINE;
-}
-
-static int reload(void)
-{
- return load_config(1);
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Customizable Comma Separated Values CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
-
diff --git a/cdr/cdr_manager.c b/cdr/cdr_manager.c
deleted file mode 100644
index 352d7d400..000000000
--- a/cdr/cdr_manager.c
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Asterisk Call Manager CDR records.
- *
- * See also
- * \arg \ref AstCDR
- * \arg \ref AstAMI
- * \arg \ref Config_ami
- * \ingroup cdr_drivers
- */
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <strings.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/manager.h"
-#include "asterisk/config.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-#define CONF_FILE "cdr_manager.conf"
-
-static char *name = "cdr_manager";
-
-static int enablecdr = 0;
-
-static int loadconfigurationfile(void)
-{
- char *cat;
- struct ast_config *cfg;
- struct ast_variable *v;
-
- cfg = ast_config_load(CONF_FILE);
- if (!cfg) {
- /* Standard configuration */
- enablecdr = 0;
- return 0;
- }
-
- cat = ast_category_browse(cfg, NULL);
- while (cat) {
- if (!strcasecmp(cat, "general")) {
- v = ast_variable_browse(cfg, cat);
- while (v) {
- if (!strcasecmp(v->name, "enabled")) {
- enablecdr = ast_true(v->value);
- }
-
- v = v->next;
- }
- }
-
- /* Next category */
- cat = ast_category_browse(cfg, cat);
- }
-
- ast_config_destroy(cfg);
- return 1;
-}
-
-static int manager_log(struct ast_cdr *cdr)
-{
- time_t t;
- struct tm timeresult;
- char strStartTime[80] = "";
- char strAnswerTime[80] = "";
- char strEndTime[80] = "";
-
- if (!enablecdr)
- return 0;
-
- t = cdr->start.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult);
-
- if (cdr->answer.tv_sec) {
- t = cdr->answer.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult);
- }
-
- t = cdr->end.tv_sec;
- ast_localtime(&t, &timeresult, NULL);
- strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult);
-
- manager_event(EVENT_FLAG_CALL, "Cdr",
- "AccountCode: %s\r\n"
- "Source: %s\r\n"
- "Destination: %s\r\n"
- "DestinationContext: %s\r\n"
- "CallerID: %s\r\n"
- "Channel: %s\r\n"
- "DestinationChannel: %s\r\n"
- "LastApplication: %s\r\n"
- "LastData: %s\r\n"
- "StartTime: %s\r\n"
- "AnswerTime: %s\r\n"
- "EndTime: %s\r\n"
- "Duration: %ld\r\n"
- "BillableSeconds: %ld\r\n"
- "Disposition: %s\r\n"
- "AMAFlags: %s\r\n"
- "UniqueID: %s\r\n"
- "UserField: %s\r\n",
- cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel,
- cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime,
- cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield);
-
- return 0;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- int res;
-
- /* Configuration file */
- if (!loadconfigurationfile())
- return AST_MODULE_LOAD_DECLINE;
-
- res = ast_cdr_register(name, "Asterisk Manager Interface CDR Backend", manager_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register Asterisk Call Manager CDR handling\n");
- }
-
- return res;
-}
-
-static int reload(void)
-{
- loadconfigurationfile();
- return 0;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Asterisk Manager Interface CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/cdr/cdr_odbc.c b/cdr/cdr_odbc.c
deleted file mode 100644
index da8327375..000000000
--- a/cdr/cdr_odbc.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003-2005, Digium, Inc.
- *
- * Brian K. West <brian@bkw.org>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief ODBC CDR Backend
- *
- * \author Brian K. West <brian@bkw.org>
- *
- * See also:
- * \arg http://www.unixodbc.org
- * \arg \ref Config_cdr
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>unixodbc</depend>
- <depend>ltdl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#ifndef __CYGWIN__
-#include <sql.h>
-#include <sqlext.h>
-#include <sqltypes.h>
-#else
-#include <windows.h>
-#include <w32api/sql.h>
-#include <w32api/sqlext.h>
-#include <w32api/sqltypes.h>
-#endif
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "ODBC";
-static char *config = "cdr_odbc.conf";
-static char *dsn = NULL, *username = NULL, *password = NULL, *table = NULL;
-static int loguniqueid = 0;
-static int usegmtime = 0;
-static int dispositionstring = 0;
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(odbc_lock);
-
-static int odbc_do_query(void);
-static int odbc_init(void);
-
-static SQLHENV ODBC_env = SQL_NULL_HANDLE; /* global ODBC Environment */
-static SQLHDBC ODBC_con; /* global ODBC Connection Handle */
-static SQLHSTMT ODBC_stmt; /* global ODBC Statement Handle */
-
-static void odbc_disconnect(void)
-{
- ODBC_stmt = SQL_NULL_HANDLE;
- SQLDisconnect(ODBC_con);
- SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
- ODBC_con = SQL_NULL_HANDLE;
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- ODBC_env = SQL_NULL_HANDLE;
- connected = 0;
-}
-
-static void build_query(struct ast_cdr *cdr, char *timestr, int timesize)
-{
- int ODBC_res;
- char sqlcmd[2048] = "";
- int res = 0;
- struct tm tm;
-
- if (usegmtime)
- gmtime_r(&cdr->start.tv_sec,&tm);
- else
- ast_localtime(&cdr->start.tv_sec, &tm, NULL);
-
- strftime(timestr, timesize, DATE_FORMAT, &tm);
- memset(sqlcmd,0,2048);
- if (loguniqueid) {
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
- "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,"
- "lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) "
- "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
- } else {
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s "
- "(calldate,clid,src,dst,dcontext,channel,dstchannel,lastapp,lastdata,"
- "duration,billsec,disposition,amaflags,accountcode) "
- "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)", table);
- }
- if (!connected) {
- res = odbc_init();
- if (res < 0) {
- odbc_disconnect();
- return;
- }
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_STMT, ODBC_con, &ODBC_stmt);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Failure in AllocStatement %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ODBC_stmt = SQL_NULL_HANDLE;
- odbc_disconnect();
- return;
- }
-
- /* We really should only have to do this once. But for some
- strange reason if I don't it blows holes in memory like
- like a shotgun. So we just do this so its safe. */
-
- ODBC_res = SQLPrepare(ODBC_stmt, (unsigned char *)sqlcmd, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in PREPARE %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ODBC_stmt = SQL_NULL_HANDLE;
- odbc_disconnect();
- return;
- }
-
- SQLBindParameter(ODBC_stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, timesize, 0, timestr, 0, NULL);
- SQLBindParameter(ODBC_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->clid), 0, cdr->clid, 0, NULL);
- SQLBindParameter(ODBC_stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->src), 0, cdr->src, 0, NULL);
- SQLBindParameter(ODBC_stmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dst), 0, cdr->dst, 0, NULL);
- SQLBindParameter(ODBC_stmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dcontext), 0, cdr->dcontext, 0, NULL);
- SQLBindParameter(ODBC_stmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->channel), 0, cdr->channel, 0, NULL);
- SQLBindParameter(ODBC_stmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->dstchannel), 0, cdr->dstchannel, 0, NULL);
- SQLBindParameter(ODBC_stmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastapp), 0, cdr->lastapp, 0, NULL);
- SQLBindParameter(ODBC_stmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->lastdata), 0, cdr->lastdata, 0, NULL);
- SQLBindParameter(ODBC_stmt, 10, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->duration, 0, NULL);
- SQLBindParameter(ODBC_stmt, 11, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->billsec, 0, NULL);
- if (dispositionstring)
- SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(ast_cdr_disp2str(cdr->disposition)) + 1, 0, ast_cdr_disp2str(cdr->disposition), 0, NULL);
- else
- SQLBindParameter(ODBC_stmt, 12, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->disposition, 0, NULL);
- SQLBindParameter(ODBC_stmt, 13, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &cdr->amaflags, 0, NULL);
- SQLBindParameter(ODBC_stmt, 14, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->accountcode), 0, cdr->accountcode, 0, NULL);
-
- if (loguniqueid) {
- SQLBindParameter(ODBC_stmt, 15, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->uniqueid), 0, cdr->uniqueid, 0, NULL);
- SQLBindParameter(ODBC_stmt, 16, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, sizeof(cdr->userfield), 0, cdr->userfield, 0, NULL);
- }
-}
-
-static int odbc_log(struct ast_cdr *cdr)
-{
- int res = 0;
- char timestr[150];
-
- ast_mutex_lock(&odbc_lock);
- build_query(cdr, timestr, sizeof(timestr));
-
- if (connected) {
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Reconnecting to dsn %s\n", dsn);
- odbc_disconnect();
- res = odbc_init();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: %s has gone away!\n", dsn);
- odbc_disconnect();
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Trying Query again!\n");
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ODBC_stmt = SQL_NULL_HANDLE;
- build_query(cdr, timestr, sizeof(timestr)); /* what a waste. If we have to reconnect, we have to build a new query */
- res = odbc_do_query();
- if (res < 0) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
- }
- }
- }
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query FAILED Call not logged!\n");
- }
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ODBC_stmt = SQL_NULL_HANDLE;
- ast_mutex_unlock(&odbc_lock);
- return 0;
-}
-
-static int odbc_unload_module(void)
-{
- ast_mutex_lock(&odbc_lock);
- if (connected) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Disconnecting from %s\n", dsn);
- SQLFreeHandle(SQL_HANDLE_STMT, ODBC_stmt);
- ODBC_stmt = SQL_NULL_HANDLE;
- odbc_disconnect();
- }
- if (dsn) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free dsn\n");
- free(dsn);
- }
- if (username) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free username\n");
- free(username);
- }
- if (password) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free password\n");
- free(password);
- }
- if (table) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: free table\n");
- free(table);
- }
-
- ast_cdr_unregister(name);
- ast_mutex_unlock(&odbc_lock);
- return 0;
-}
-
-static int odbc_load_module(void)
-{
- int res = 0;
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *tmp;
-
- ast_mutex_lock(&odbc_lock);
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_WARNING, "cdr_odbc: Unable to load config for ODBC CDR's: %s\n", config);
- res = AST_MODULE_LOAD_DECLINE;
- goto out;
- }
-
- var = ast_variable_browse(cfg, "global");
- if (!var) {
- /* nothing configured */
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dsn");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cdr_odbc: dsn not specified. Assuming asteriskdb\n");
- tmp = "asteriskdb";
- }
- dsn = strdup(tmp);
- if (dsn == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","dispositionstring");
- if (tmp) {
- dispositionstring = ast_true(tmp);
- } else {
- dispositionstring = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","username");
- if (tmp) {
- username = strdup(tmp);
- if (username == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","password");
- if (tmp) {
- password = strdup(tmp);
- if (password == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
- }
-
- tmp = ast_variable_retrieve(cfg,"global","loguniqueid");
- if (tmp) {
- loguniqueid = ast_true(tmp);
- if (loguniqueid) {
- ast_log(LOG_DEBUG,"cdr_odbc: Logging uniqueid\n");
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
- }
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging uniqueid\n");
- loguniqueid = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","usegmtime");
- if (tmp) {
- usegmtime = ast_true(tmp);
- if (usegmtime) {
- ast_log(LOG_DEBUG,"cdr_odbc: Logging in GMT\n");
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
- }
- } else {
- ast_log(LOG_DEBUG,"cdr_odbc: Not logging in GMT\n");
- usegmtime = 0;
- }
-
- tmp = ast_variable_retrieve(cfg,"global","table");
- if (tmp == NULL) {
- ast_log(LOG_WARNING,"cdr_odbc: table not specified. Assuming cdr\n");
- tmp = "cdr";
- }
- table = strdup(tmp);
- if (table == NULL) {
- ast_log(LOG_ERROR,"cdr_odbc: Out of memory error.\n");
- res = -1;
- goto out;
- }
-
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: dsn is %s\n",dsn);
- if (username)
- {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: username is %s\n",username);
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: password is [secret]\n");
- }
- else
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: retreiving username and password from odbc config\n");
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: table is %s\n",table);
- }
-
- res = odbc_init();
- if (res < 0) {
- ast_log(LOG_ERROR, "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
- if (option_verbose > 2) {
- ast_verbose( VERBOSE_PREFIX_3 "cdr_odbc: Unable to connect to datasource: %s\n", dsn);
- }
- }
- res = ast_cdr_register(name, ast_module_info->description, odbc_log);
- if (res) {
- ast_log(LOG_ERROR, "cdr_odbc: Unable to register ODBC CDR handling\n");
- }
-out:
- if (cfg)
- ast_config_destroy(cfg);
- ast_mutex_unlock(&odbc_lock);
- return res;
-}
-
-static int odbc_do_query(void)
-{
- int ODBC_res;
- ODBC_res = SQLExecute(ODBC_stmt);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error in Query %d\n", ODBC_res);
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Query Successful!\n");
- connected = 1;
- }
- return 0;
-}
-
-static int odbc_init(void)
-{
- int ODBC_res;
-
- if (ODBC_env == SQL_NULL_HANDLE || connected == 0) {
- ODBC_res = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &ODBC_env);
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHandle\n");
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLSetEnvAttr(ODBC_env, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SetEnv\n");
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- ODBC_env = SQL_NULL_HANDLE;
- connected = 0;
- return -1;
- }
-
- ODBC_res = SQLAllocHandle(SQL_HANDLE_DBC, ODBC_env, &ODBC_con);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error AllocHDB %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- ODBC_env = SQL_NULL_HANDLE;
- connected = 0;
- return -1;
- }
- SQLSetConnectAttr(ODBC_con, SQL_LOGIN_TIMEOUT, (SQLPOINTER *)10, 0);
- }
-
- /* Note that the username and password could be NULL here, but that is allowed in ODBC.
- In this case, the default username and password will be used from odbc.conf */
- ODBC_res = SQLConnect(ODBC_con, (SQLCHAR*)dsn, SQL_NTS, (SQLCHAR*)username, SQL_NTS, (SQLCHAR*)password, SQL_NTS);
-
- if ((ODBC_res != SQL_SUCCESS) && (ODBC_res != SQL_SUCCESS_WITH_INFO)) {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Error SQLConnect %d\n", ODBC_res);
- SQLFreeHandle(SQL_HANDLE_DBC, ODBC_con);
- ODBC_con = SQL_NULL_HANDLE;
- SQLFreeHandle(SQL_HANDLE_ENV, ODBC_env);
- ODBC_env = SQL_NULL_HANDLE;
- connected = 0;
- return -1;
- } else {
- if (option_verbose > 10)
- ast_verbose( VERBOSE_PREFIX_4 "cdr_odbc: Connected to %s\n", dsn);
- connected = 1;
- }
- return 0;
-}
-
-static int load_module(void)
-{
- return odbc_load_module();
-}
-
-static int unload_module(void)
-{
- return odbc_unload_module();
-}
-
-static int reload(void)
-{
- odbc_unload_module();
- return odbc_load_module();
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ODBC CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/cdr/cdr_pgsql.c b/cdr/cdr_pgsql.c
deleted file mode 100644
index a2144a712..000000000
--- a/cdr/cdr_pgsql.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2003 - 2006
- *
- * Matthew D. Hardeman <mhardemn@papersoft.com>
- * Adapted from the MySQL CDR logger originally by James Sharp
- *
- * Modified September 2003
- * Matthew D. Hardeman <mhardemn@papersoft.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief PostgreSQL CDR logger
- *
- * \author Matthew D. Hardeman <mhardemn@papersoft.com>
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.postgresql.org/
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>pgsql</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <libpq-fe.h>
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk.h"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "pgsql";
-static char *config = "cdr_pgsql.conf";
-static char *pghostname = NULL, *pgdbname = NULL, *pgdbuser = NULL, *pgpassword = NULL, *pgdbport = NULL, *table = NULL;
-static int connected = 0;
-
-AST_MUTEX_DEFINE_STATIC(pgsql_lock);
-
-static PGconn *conn = NULL;
-
-static int pgsql_log(struct ast_cdr *cdr)
-{
- struct tm tm;
- time_t t = cdr->start.tv_sec;
- char sqlcmd[2048] = "", timestr[128];
- char *pgerror;
- PGresult *result;
-
- ast_mutex_lock(&pgsql_lock);
-
- ast_localtime(&t, &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
-
- if ((!connected) && pghostname && pgdbuser && pgpassword && pgdbname) {
- conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
- if (PQstatus(conn) != CONNECTION_BAD) {
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. Calls will not be logged!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- PQfinish(conn);
- conn = NULL;
- }
- }
-
- if (connected) {
- char *clid=NULL, *dcontext=NULL, *channel=NULL, *dstchannel=NULL, *lastapp=NULL, *lastdata=NULL;
- char *src=NULL, *dst=NULL, *uniqueid=NULL, *userfield=NULL;
- int pgerr;
-
- /* Maximum space needed would be if all characters needed to be escaped, plus a trailing NULL */
- if ((clid = alloca(strlen(cdr->clid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, clid, cdr->clid, strlen(cdr->clid), &pgerr);
- if ((dcontext = alloca(strlen(cdr->dcontext) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dcontext, cdr->dcontext, strlen(cdr->dcontext), &pgerr);
- if ((channel = alloca(strlen(cdr->channel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, channel, cdr->channel, strlen(cdr->channel), &pgerr);
- if ((dstchannel = alloca(strlen(cdr->dstchannel) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dstchannel, cdr->dstchannel, strlen(cdr->dstchannel), &pgerr);
- if ((lastapp = alloca(strlen(cdr->lastapp) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastapp, cdr->lastapp, strlen(cdr->lastapp), &pgerr);
- if ((lastdata = alloca(strlen(cdr->lastdata) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, lastdata, cdr->lastdata, strlen(cdr->lastdata), &pgerr);
- if ((uniqueid = alloca(strlen(cdr->uniqueid) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, uniqueid, cdr->uniqueid, strlen(cdr->uniqueid), &pgerr);
- if ((userfield = alloca(strlen(cdr->userfield) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, userfield, cdr->userfield, strlen(cdr->userfield), &pgerr);
- if ((src = alloca(strlen(cdr->src) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, src, cdr->src, strlen(cdr->src), &pgerr);
- if ((dst = alloca(strlen(cdr->dst) * 2 + 1)) != NULL)
- PQescapeStringConn(conn, dst, cdr->dst, strlen(cdr->dst), &pgerr);
-
- /* Check for all alloca failures above at once */
- if ((!clid) || (!dcontext) || (!channel) || (!dstchannel) || (!lastapp) || (!lastdata) || (!uniqueid) || (!userfield) || (!src) || (!dst)) {
- ast_log(LOG_ERROR, "cdr_pgsql: Out of memory error (insert fails)\n");
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
-
- if (option_debug > 1)
- ast_log(LOG_DEBUG, "cdr_pgsql: inserting a CDR record.\n");
-
- snprintf(sqlcmd,sizeof(sqlcmd),"INSERT INTO %s (calldate,clid,src,dst,dcontext,channel,dstchannel,"
- "lastapp,lastdata,duration,billsec,disposition,amaflags,accountcode,uniqueid,userfield) VALUES"
- " ('%s','%s','%s','%s','%s', '%s','%s','%s','%s',%ld,%ld,'%s',%ld,'%s','%s','%s')",
- table, timestr, clid, src, dst, dcontext, channel, dstchannel, lastapp, lastdata,
- cdr->duration,cdr->billsec,ast_cdr_disp2str(cdr->disposition),cdr->amaflags, cdr->accountcode, uniqueid, userfield);
-
- if (option_debug > 2)
- ast_log(LOG_DEBUG, "cdr_pgsql: SQL command executed: %s\n",sqlcmd);
-
- /* Test to be sure we're still connected... */
- /* If we're connected, and connection is working, good. */
- /* Otherwise, attempt reconnect. If it fails... sorry... */
- if (PQstatus(conn) == CONNECTION_OK) {
- connected = 1;
- } else {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection was lost... attempting to reconnect.\n");
- PQreset(conn);
- if (PQstatus(conn) == CONNECTION_OK) {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n");
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to reconnect to database server %s. Calls will not be logged!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- PQfinish(conn);
- conn = NULL;
- connected = 0;
- ast_mutex_unlock(&pgsql_lock);
- return -1;
- }
- }
- result = PQexec(conn, sqlcmd);
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- pgerror = PQresultErrorMessage(result);
- ast_log(LOG_ERROR,"cdr_pgsql: Failed to insert call detail record into database!\n");
- ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror);
- ast_log(LOG_ERROR,"cdr_pgsql: Connection may have been lost... attempting to reconnect.\n");
- PQreset(conn);
- if (PQstatus(conn) == CONNECTION_OK) {
- ast_log(LOG_ERROR, "cdr_pgsql: Connection reestablished.\n");
- connected = 1;
- PQclear(result);
- result = PQexec(conn, sqlcmd);
- if (PQresultStatus(result) != PGRES_COMMAND_OK) {
- pgerror = PQresultErrorMessage(result);
- ast_log(LOG_ERROR,"cdr_pgsql: HARD ERROR! Attempted reconnection failed. DROPPING CALL RECORD!\n");
- ast_log(LOG_ERROR,"cdr_pgsql: Reason: %s\n", pgerror);
- }
- }
- ast_mutex_unlock(&pgsql_lock);
- PQclear(result);
- return -1;
- }
- PQclear(result);
- }
- ast_mutex_unlock(&pgsql_lock);
- return 0;
-}
-
-static int my_unload_module(void)
-{
- PQfinish(conn);
- if (pghostname)
- free(pghostname);
- if (pgdbname)
- free(pgdbname);
- if (pgdbuser)
- free(pgdbuser);
- if (pgpassword)
- free(pgpassword);
- if (pgdbport)
- free(pgdbport);
- if (table)
- free(table);
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int process_my_load_module(struct ast_config *cfg)
-{
- struct ast_variable *var;
- char *pgerror;
- const char *tmp;
-
- if (!(var = ast_variable_browse(cfg, "global")))
- return 0;
-
- if (!(tmp = ast_variable_retrieve(cfg,"global","hostname"))) {
- ast_log(LOG_WARNING,"PostgreSQL server hostname not specified. Assuming unix socket connection\n");
- tmp = ""; /* connect via UNIX-socket by default */
- }
-
- if (!(pghostname = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "dbname"))) {
- ast_log(LOG_WARNING,"PostgreSQL database not specified. Assuming asterisk\n");
- tmp = "asteriskcdrdb";
- }
-
- if (!(pgdbname = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "user"))) {
- ast_log(LOG_WARNING,"PostgreSQL database user not specified. Assuming asterisk\n");
- tmp = "asterisk";
- }
-
- if (!(pgdbuser = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "password"))) {
- ast_log(LOG_WARNING,"PostgreSQL database password not specified. Assuming blank\n");
- tmp = "";
- }
-
- if (!(pgpassword = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg,"global","port"))) {
- ast_log(LOG_WARNING,"PostgreSQL database port not specified. Using default 5432.\n");
- tmp = "5432";
- }
-
- if (!(pgdbport = ast_strdup(tmp)))
- return -1;
-
- if (!(tmp = ast_variable_retrieve(cfg, "global", "table"))) {
- ast_log(LOG_WARNING,"CDR table not specified. Assuming cdr\n");
- tmp = "cdr";
- }
-
- if (!(table = ast_strdup(tmp)))
- return -1;
-
- if (option_debug) {
- if (ast_strlen_zero(pghostname))
- ast_log(LOG_DEBUG, "cdr_pgsql: using default unix socket\n");
- else
- ast_log(LOG_DEBUG, "cdr_pgsql: got hostname of %s\n", pghostname);
- ast_log(LOG_DEBUG, "cdr_pgsql: got port of %s\n", pgdbport);
- ast_log(LOG_DEBUG, "cdr_pgsql: got user of %s\n", pgdbuser);
- ast_log(LOG_DEBUG, "cdr_pgsql: got dbname of %s\n", pgdbname);
- ast_log(LOG_DEBUG, "cdr_pgsql: got password of %s\n", pgpassword);
- ast_log(LOG_DEBUG, "cdr_pgsql: got sql table name of %s\n", table);
- }
-
- conn = PQsetdbLogin(pghostname, pgdbport, NULL, NULL, pgdbname, pgdbuser, pgpassword);
- if (PQstatus(conn) != CONNECTION_BAD) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Successfully connected to PostgreSQL database.\n");
- connected = 1;
- } else {
- pgerror = PQerrorMessage(conn);
- ast_log(LOG_ERROR, "cdr_pgsql: Unable to connect to database server %s. CALLS WILL NOT BE LOGGED!!\n", pghostname);
- ast_log(LOG_ERROR, "cdr_pgsql: Reason: %s\n", pgerror);
- connected = 0;
- }
-
- return ast_cdr_register(name, ast_module_info->description, pgsql_log);
-}
-
-static int my_load_module(void)
-{
- struct ast_config *cfg;
- int res;
-
- if (!(cfg = ast_config_load(config))) {
- ast_log(LOG_WARNING, "Unable to load config for PostgreSQL CDR's: %s\n", config);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- res = process_my_load_module(cfg);
- ast_config_destroy(cfg);
-
- return res;
-}
-
-static int load_module(void)
-{
- return my_load_module();
-}
-
-static int unload_module(void)
-{
- return my_unload_module();
-}
-
-static int reload(void)
-{
- int res;
- ast_mutex_lock(&pgsql_lock);
- my_unload_module();
- res = my_load_module();
- ast_mutex_unlock(&pgsql_lock);
- return res;
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "PostgreSQL CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );
diff --git a/cdr/cdr_radius.c b/cdr/cdr_radius.c
deleted file mode 100644
index 6d890e764..000000000
--- a/cdr/cdr_radius.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2005, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief RADIUS CDR Support
- * \author Philippe Sultan
- *
- * \arg See also \ref AstCDR
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>radius</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Rev$")
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <time.h>
-#include <sys/types.h>
-#include <radiusclient-ng.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-#include "asterisk/options.h"
-
-/*! ISO 8601 standard format */
-#define DATE_FORMAT "%Y-%m-%d %T %z"
-
-#define VENDOR_CODE 22736
-
-enum {
- PW_AST_ACCT_CODE = 101,
- PW_AST_SRC = 102,
- PW_AST_DST = 103,
- PW_AST_DST_CTX = 104,
- PW_AST_CLID = 105,
- PW_AST_CHAN = 106,
- PW_AST_DST_CHAN = 107,
- PW_AST_LAST_APP = 108,
- PW_AST_LAST_DATA = 109,
- PW_AST_START_TIME = 110,
- PW_AST_ANSWER_TIME = 111,
- PW_AST_END_TIME = 112,
- PW_AST_DURATION = 113,
- PW_AST_BILL_SEC = 114,
- PW_AST_DISPOSITION = 115,
- PW_AST_AMA_FLAGS = 116,
- PW_AST_UNIQUE_ID = 117,
- PW_AST_USER_FIELD = 118
-};
-
-enum {
- /*! Log dates and times in UTC */
- RADIUS_FLAG_USEGMTIME = (1 << 0),
- /*! Log Unique ID */
- RADIUS_FLAG_LOGUNIQUEID = (1 << 1),
- /*! Log User Field */
- RADIUS_FLAG_LOGUSERFIELD = (1 << 2)
-};
-
-static char *desc = "RADIUS CDR Backend";
-static char *name = "radius";
-static char *cdr_config = "cdr.conf";
-
-static char radiuscfg[PATH_MAX] = "/etc/radiusclient-ng/radiusclient.conf";
-
-static struct ast_flags global_flags = { RADIUS_FLAG_USEGMTIME | RADIUS_FLAG_LOGUNIQUEID | RADIUS_FLAG_LOGUSERFIELD };
-
-static rc_handle *rh = NULL;
-
-static int build_radius_record(VALUE_PAIR **send, struct ast_cdr *cdr)
-{
- int recordtype = PW_STATUS_STOP;
- struct tm tm;
- char timestr[128];
- char *tmp;
-
- if (!rc_avpair_add(rh, send, PW_ACCT_STATUS_TYPE, &recordtype, 0, 0))
- return -1;
-
- /* Account code */
- if (!rc_avpair_add(rh, send, PW_AST_ACCT_CODE, &cdr->accountcode, strlen(cdr->accountcode), VENDOR_CODE))
- return -1;
-
- /* Source */
- if (!rc_avpair_add(rh, send, PW_AST_SRC, &cdr->src, strlen(cdr->src), VENDOR_CODE))
- return -1;
-
- /* Destination */
- if (!rc_avpair_add(rh, send, PW_AST_DST, &cdr->dst, strlen(cdr->dst), VENDOR_CODE))
- return -1;
-
- /* Destination context */
- if (!rc_avpair_add(rh, send, PW_AST_DST_CTX, &cdr->dcontext, strlen(cdr->dcontext), VENDOR_CODE))
- return -1;
-
- /* Caller ID */
- if (!rc_avpair_add(rh, send, PW_AST_CLID, &cdr->clid, strlen(cdr->clid), VENDOR_CODE))
- return -1;
-
- /* Channel */
- if (!rc_avpair_add(rh, send, PW_AST_CHAN, &cdr->channel, strlen(cdr->channel), VENDOR_CODE))
- return -1;
-
- /* Destination Channel */
- if (!rc_avpair_add(rh, send, PW_AST_DST_CHAN, &cdr->dstchannel, strlen(cdr->dstchannel), VENDOR_CODE))
- return -1;
-
- /* Last Application */
- if (!rc_avpair_add(rh, send, PW_AST_LAST_APP, &cdr->lastapp, strlen(cdr->lastapp), VENDOR_CODE))
- return -1;
-
- /* Last Data */
- if (!rc_avpair_add(rh, send, PW_AST_LAST_DATA, &cdr->lastdata, strlen(cdr->lastdata), VENDOR_CODE))
- return -1;
-
-
- /* Start Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->start.tv_sec), &tm);
- else
- ast_localtime(&(cdr->start.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_START_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* Answer Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->answer.tv_sec), &tm);
- else
- ast_localtime(&(cdr->answer.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_ANSWER_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* End Time */
- if (ast_test_flag(&global_flags, RADIUS_FLAG_USEGMTIME))
- gmtime_r(&(cdr->end.tv_sec), &tm);
- else
- ast_localtime(&(cdr->end.tv_sec), &tm, NULL);
- strftime(timestr, sizeof(timestr), DATE_FORMAT, &tm);
- if (!rc_avpair_add(rh, send, PW_AST_END_TIME, timestr, strlen(timestr), VENDOR_CODE))
- return -1;
-
- /* Duration */
- if (!rc_avpair_add(rh, send, PW_AST_DURATION, &cdr->duration, 0, VENDOR_CODE))
- return -1;
-
- /* Billable seconds */
- if (!rc_avpair_add(rh, send, PW_AST_BILL_SEC, &cdr->billsec, 0, VENDOR_CODE))
- return -1;
-
- /* Disposition */
- tmp = ast_cdr_disp2str(cdr->disposition);
- if (!rc_avpair_add(rh, send, PW_AST_DISPOSITION, tmp, strlen(tmp), VENDOR_CODE))
- return -1;
-
- /* AMA Flags */
- tmp = ast_cdr_flags2str(cdr->amaflags);
- if (!rc_avpair_add(rh, send, PW_AST_AMA_FLAGS, tmp, strlen(tmp), VENDOR_CODE))
- return -1;
-
- if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUNIQUEID)) {
- /* Unique ID */
- if (!rc_avpair_add(rh, send, PW_AST_UNIQUE_ID, &cdr->uniqueid, strlen(cdr->uniqueid), VENDOR_CODE))
- return -1;
- }
-
- if (ast_test_flag(&global_flags, RADIUS_FLAG_LOGUSERFIELD)) {
- /* append the user field */
- if (!rc_avpair_add(rh, send, PW_AST_USER_FIELD, &cdr->userfield, strlen(cdr->userfield), VENDOR_CODE))
- return -1;
- }
-
- /* Setting Acct-Session-Id & User-Name attributes for proper generation
- of Acct-Unique-Session-Id on server side */
- /* Channel */
- if (!rc_avpair_add(rh, send, PW_USER_NAME, &cdr->channel, strlen(cdr->channel), 0))
- return -1;
-
- /* Unique ID */
- if (!rc_avpair_add(rh, send, PW_ACCT_SESSION_ID, &cdr->uniqueid, strlen(cdr->uniqueid), 0))
- return -1;
-
- return 0;
-}
-
-static int radius_log(struct ast_cdr *cdr)
-{
- int result = ERROR_RC;
- VALUE_PAIR *send = NULL;
-
- if (build_radius_record(&send, cdr)) {
- if (option_debug)
- ast_log(LOG_DEBUG, "Unable to create RADIUS record. CDR not recorded!\n");
- return result;
- }
-
- result = rc_acct(rh, 0, send);
- if (result != OK_RC)
- ast_log(LOG_ERROR, "Failed to record Radius CDR record!\n");
-
- return result;
-}
-
-static int unload_module(void)
-{
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- struct ast_config *cfg;
- int res;
- const char *tmp;
-
- if ((cfg = ast_config_load(cdr_config))) {
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "usegmtime")), RADIUS_FLAG_USEGMTIME);
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguniqueid")), RADIUS_FLAG_LOGUNIQUEID);
- ast_set2_flag(&global_flags, ast_true(ast_variable_retrieve(cfg, "radius", "loguserfield")), RADIUS_FLAG_LOGUSERFIELD);
- if ((tmp = ast_variable_retrieve(cfg, "radius", "radiuscfg")))
- ast_copy_string(radiuscfg, tmp, sizeof(radiuscfg));
- ast_config_destroy(cfg);
- } else
- return AST_MODULE_LOAD_DECLINE;
-
- /* start logging */
- rc_openlog("asterisk");
-
- /* read radiusclient-ng config file */
- if (!(rh = rc_read_config(radiuscfg))) {
- ast_log(LOG_NOTICE, "Cannot load radiusclient-ng configuration file %s.\n", radiuscfg);
- return AST_MODULE_LOAD_DECLINE;
- }
-
- /* read radiusclient-ng dictionaries */
- if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary"))) {
- ast_log(LOG_NOTICE, "Cannot load radiusclient-ng dictionary file.\n");
- return AST_MODULE_LOAD_DECLINE;
- }
-
- res = ast_cdr_register(name, desc, radius_log);
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "RADIUS CDR Backend");
diff --git a/cdr/cdr_sqlite.c b/cdr/cdr_sqlite.c
deleted file mode 100644
index 5aa8a5154..000000000
--- a/cdr/cdr_sqlite.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2005, Holger Schurig
- *
- *
- * Ideas taken from other cdr_*.c files
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief Store CDR records in a SQLite database.
- *
- * \author Holger Schurig <hs4233@mail.mn-solutions.de>
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.sqlite.org/
- *
- * Creates the database and table on-the-fly
- * \ingroup cdr_drivers
- */
-
-/*** MODULEINFO
- <depend>sqlite</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sqlite.h>
-
-#include "asterisk/channel.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-#include "asterisk/utils.h"
-
-#define LOG_UNIQUEID 0
-#define LOG_USERFIELD 0
-
-/* When you change the DATE_FORMAT, be sure to change the CHAR(19) below to something else */
-#define DATE_FORMAT "%Y-%m-%d %T"
-
-static char *name = "sqlite";
-static sqlite* db = NULL;
-
-AST_MUTEX_DEFINE_STATIC(sqlite_lock);
-
-/*! \brief SQL table format */
-static char sql_create_table[] = "CREATE TABLE cdr ("
-" AcctId INTEGER PRIMARY KEY,"
-" clid VARCHAR(80),"
-" src VARCHAR(80),"
-" dst VARCHAR(80),"
-" dcontext VARCHAR(80),"
-" channel VARCHAR(80),"
-" dstchannel VARCHAR(80),"
-" lastapp VARCHAR(80),"
-" lastdata VARCHAR(80),"
-" start CHAR(19),"
-" answer CHAR(19),"
-" end CHAR(19),"
-" duration INTEGER,"
-" billsec INTEGER,"
-" disposition INTEGER,"
-" amaflags INTEGER,"
-" accountcode VARCHAR(20)"
-#if LOG_UNIQUEID
-" ,uniqueid VARCHAR(32)"
-#endif
-#if LOG_USERFIELD
-" ,userfield VARCHAR(255)"
-#endif
-");";
-
-static int sqlite_log(struct ast_cdr *cdr)
-{
- int res = 0;
- char *zErr = 0;
- struct tm tm;
- time_t t;
- char startstr[80], answerstr[80], endstr[80];
- int count;
-
- ast_mutex_lock(&sqlite_lock);
-
- t = cdr->start.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(startstr, sizeof(startstr), DATE_FORMAT, &tm);
-
- t = cdr->answer.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(answerstr, sizeof(answerstr), DATE_FORMAT, &tm);
-
- t = cdr->end.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
-
- for(count=0; count<5; count++) {
- res = sqlite_exec_printf(db,
- "INSERT INTO cdr ("
- "clid,src,dst,dcontext,"
- "channel,dstchannel,lastapp,lastdata, "
- "start,answer,end,"
- "duration,billsec,disposition,amaflags, "
- "accountcode"
-# if LOG_UNIQUEID
- ",uniqueid"
-# endif
-# if LOG_USERFIELD
- ",userfield"
-# endif
- ") VALUES ("
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', '%q', "
- "'%q', '%q', '%q', "
- "%d, %d, %d, %d, "
- "'%q'"
-# if LOG_UNIQUEID
- ",'%q'"
-# endif
-# if LOG_USERFIELD
- ",'%q'"
-# endif
- ")", NULL, NULL, &zErr,
- cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
- cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
- startstr, answerstr, endstr,
- cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
- cdr->accountcode
-# if LOG_UNIQUEID
- ,cdr->uniqueid
-# endif
-# if LOG_USERFIELD
- ,cdr->userfield
-# endif
- );
- if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
- break;
- usleep(200);
- }
-
- if (zErr) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- }
-
- ast_mutex_unlock(&sqlite_lock);
- return res;
-}
-
-static int unload_module(void)
-{
- if (db)
- sqlite_close(db);
- ast_cdr_unregister(name);
- return 0;
-}
-
-static int load_module(void)
-{
- char *zErr;
- char fn[PATH_MAX];
- int res;
-
- /* is the database there? */
- snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
- db = sqlite_open(fn, 0660, &zErr);
- if (!db) {
- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
- free(zErr);
- return -1;
- }
-
- /* is the table there? */
- res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
- if (res) {
- res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
- if (res) {
- ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
- free(zErr);
- goto err;
- }
-
- /* TODO: here we should probably create an index */
- }
-
- res = ast_cdr_register(name, ast_module_info->description, sqlite_log);
- if (res) {
- ast_log(LOG_ERROR, "Unable to register SQLite CDR handling\n");
- return -1;
- }
- return 0;
-
-err:
- if (db)
- sqlite_close(db);
- return -1;
-}
-
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "SQLite CDR Backend");
diff --git a/cdr/cdr_tds.c b/cdr/cdr_tds.c
deleted file mode 100644
index 4e44e4ee1..000000000
--- a/cdr/cdr_tds.c
+++ /dev/null
@@ -1,630 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2004 - 2006, Digium, Inc.
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- *
- * \brief FreeTDS CDR logger
- *
- * See also
- * \arg \ref Config_cdr
- * \arg http://www.freetds.org/
- * \ingroup cdr_drivers
- */
-
-/*! \verbatim
- *
- * Table Structure for `cdr`
- *
- * Created on: 05/20/2004 16:16
- * Last changed on: 07/27/2004 20:01
-
-CREATE TABLE [dbo].[cdr] (
- [accountcode] [varchar] (20) NULL ,
- [src] [varchar] (80) NULL ,
- [dst] [varchar] (80) NULL ,
- [dcontext] [varchar] (80) NULL ,
- [clid] [varchar] (80) NULL ,
- [channel] [varchar] (80) NULL ,
- [dstchannel] [varchar] (80) NULL ,
- [lastapp] [varchar] (80) NULL ,
- [lastdata] [varchar] (80) NULL ,
- [start] [datetime] NULL ,
- [answer] [datetime] NULL ,
- [end] [datetime] NULL ,
- [duration] [int] NULL ,
- [billsec] [int] NULL ,
- [disposition] [varchar] (20) NULL ,
- [amaflags] [varchar] (16) NULL ,
- [uniqueid] [varchar] (32) NULL ,
- [userfield] [varchar] (256) NULL
-) ON [PRIMARY]
-
-\endverbatim
-
-*/
-
-/*** MODULEINFO
- <depend>freetds</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
-#include <math.h>
-
-#include <tds.h>
-#include <tdsconvert.h>
-#include <ctype.h>
-
-#include "asterisk/config.h"
-#include "asterisk/options.h"
-#include "asterisk/channel.h"
-#include "asterisk/cdr.h"
-#include "asterisk/module.h"
-#include "asterisk/logger.h"
-
-#ifdef FREETDS_PRE_0_62
-#warning "You have older TDS, you should upgrade!"
-#endif
-
-#define DATE_FORMAT "%Y/%m/%d %T"
-
-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;
-static int has_userfield = 0;
-
-AST_MUTEX_DEFINE_STATIC(tds_lock);
-
-static TDSSOCKET *tds;
-static TDSLOGIN *login;
-static TDSCONTEXT *context;
-
-static char *anti_injection(const char *, int);
-static void get_date(char *, size_t, struct timeval);
-
-static int mssql_connect(void);
-static int mssql_disconnect(void);
-
-static int tds_log(struct ast_cdr *cdr)
-{
- char sqlcmd[2048], start[80], answer[80], end[80];
- char *accountcode, *src, *dst, *dcontext, *clid, *channel, *dstchannel, *lastapp, *lastdata, *uniqueid, *userfield = NULL;
- int res = 0;
- int retried = 0;
-#ifdef FREETDS_PRE_0_62
- TDS_INT result_type;
-#endif
-
- ast_mutex_lock(&tds_lock);
-
- memset(sqlcmd, 0, 2048);
-
- accountcode = anti_injection(cdr->accountcode, 20);
- src = anti_injection(cdr->src, 80);
- dst = anti_injection(cdr->dst, 80);
- dcontext = anti_injection(cdr->dcontext, 80);
- clid = anti_injection(cdr->clid, 80);
- channel = anti_injection(cdr->channel, 80);
- dstchannel = anti_injection(cdr->dstchannel, 80);
- lastapp = anti_injection(cdr->lastapp, 80);
- lastdata = anti_injection(cdr->lastdata, 80);
- uniqueid = anti_injection(cdr->uniqueid, 32);
-
- if (has_userfield) {
- userfield = anti_injection(cdr->userfield, AST_MAX_USER_FIELD);
- }
-
- get_date(start, sizeof(start), cdr->start);
- get_date(answer, sizeof(answer), cdr->answer);
- get_date(end, sizeof(end), cdr->end);
-
- if (has_userfield) {
- snprintf(
- sqlcmd,
- sizeof(sqlcmd),
- "INSERT INTO %s "
- "("
- "accountcode, "
- "src, "
- "dst, "
- "dcontext, "
- "clid, "
- "channel, "
- "dstchannel, "
- "lastapp, "
- "lastdata, "
- "start, "
- "answer, "
- "[end], "
- "duration, "
- "billsec, "
- "disposition, "
- "amaflags, "
- "uniqueid, "
- "userfield"
- ") "
- "VALUES "
- "("
- "'%s', " /* accountcode */
- "'%s', " /* src */
- "'%s', " /* dst */
- "'%s', " /* dcontext */
- "'%s', " /* clid */
- "'%s', " /* channel */
- "'%s', " /* dstchannel */
- "'%s', " /* lastapp */
- "'%s', " /* lastdata */
- "%s, " /* start */
- "%s, " /* answer */
- "%s, " /* end */
- "%ld, " /* duration */
- "%ld, " /* billsec */
- "'%s', " /* disposition */
- "'%s', " /* amaflags */
- "'%s', " /* uniqueid */
- "'%s'" /* userfield */
- ")",
- table,
- accountcode,
- src,
- dst,
- dcontext,
- clid,
- channel,
- dstchannel,
- lastapp,
- lastdata,
- start,
- answer,
- end,
- cdr->duration,
- cdr->billsec,
- ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags),
- uniqueid,
- userfield
- );
- } else {
- snprintf(
- sqlcmd,
- sizeof(sqlcmd),
- "INSERT INTO %s "
- "("
- "accountcode, "
- "src, "
- "dst, "
- "dcontext, "
- "clid, "
- "channel, "
- "dstchannel, "
- "lastapp, "
- "lastdata, "
- "start, "
- "answer, "
- "[end], "
- "duration, "
- "billsec, "
- "disposition, "
- "amaflags, "
- "uniqueid"
- ") "
- "VALUES "
- "("
- "'%s', " /* accountcode */
- "'%s', " /* src */
- "'%s', " /* dst */
- "'%s', " /* dcontext */
- "'%s', " /* clid */
- "'%s', " /* channel */
- "'%s', " /* dstchannel */
- "'%s', " /* lastapp */
- "'%s', " /* lastdata */
- "%s, " /* start */
- "%s, " /* answer */
- "%s, " /* end */
- "%ld, " /* duration */
- "%ld, " /* billsec */
- "'%s', " /* disposition */
- "'%s', " /* amaflags */
- "'%s'" /* uniqueid */
- ")",
- table,
- accountcode,
- src,
- dst,
- dcontext,
- clid,
- channel,
- dstchannel,
- lastapp,
- lastdata,
- start,
- answer,
- end,
- cdr->duration,
- cdr->billsec,
- ast_cdr_disp2str(cdr->disposition),
- ast_cdr_flags2str(cdr->amaflags),
- uniqueid
- );
- }
-
- do {
- if (!connected) {
- if (mssql_connect())
- ast_log(LOG_ERROR, "Failed to reconnect to SQL database.\n");
- else
- ast_log(LOG_WARNING, "Reconnected to SQL database.\n");
-
- retried = 1; /* note that we have now tried */
- }
-
-#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))
-#else
- if (!connected || (tds_submit_query(tds, sqlcmd) != TDS_SUCCEED) || (tds_process_simple_query(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);
-
- free(accountcode);
- free(src);
- free(dst);
- free(dcontext);
- free(clid);
- free(channel);
- free(dstchannel);
- free(lastapp);
- free(lastdata);
- free(uniqueid);
- if (userfield) {
- free(userfield);
- }
-
- ast_mutex_unlock(&tds_lock);
-
- return res;
-}
-
-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 = malloc(len + 1)) == NULL)
- {
- ast_log(LOG_ERROR, "cdr_tds: Out of memory error\n");
- return NULL;
- }
- memset(buf, 0, len);
-
- buf_ptr = buf;
-
- /* Escape single quotes */
- for (; *str && strlen(buf) < len; str++)
- {
- if (*str == '\'')
- *buf_ptr++ = '\'';
- *buf_ptr++ = *str;
- }
- *buf_ptr = '\0';
-
- /* Erase known bad input */
- for (idx=0; *known_bad[idx]; idx++)
- {
- while((srh_ptr = strcasestr(buf, known_bad[idx])))
- {
- memmove(srh_ptr, srh_ptr+strlen(known_bad[idx]), strlen(srh_ptr+strlen(known_bad[idx]))+1);
- }
- }
-
- return buf;
-}
-
-static void get_date(char *dateField, size_t length, struct timeval tv)
-{
- struct tm tm;
- time_t t;
- char buf[80];
-
- /* To make sure we have date variable if not insert null to SQL */
- if (!ast_tvzero(tv))
- {
- t = tv.tv_sec;
- ast_localtime(&t, &tm, NULL);
- strftime(buf, sizeof(buf), DATE_FORMAT, &tm);
- snprintf(dateField, length, "'%s'", buf);
- }
- else
- {
- ast_copy_string(dateField, "null", length);
- }
-}
-
-static int mssql_disconnect(void)
-{
- if (tds) {
- tds_free_socket(tds);
- tds = NULL;
- }
-
- if (context) {
- tds_free_context(context);
- context = NULL;
- }
-
- if (login) {
- tds_free_login(login);
- login = NULL;
- }
-
- connected = 0;
-
- return 0;
-}
-
-static int mssql_connect(void)
-{
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- TDSCONNECTION *connection = NULL;
-#else
- TDSCONNECTINFO *connection = NULL;
-#endif
- char query[512];
-
- /* Connect to M$SQL Server */
- if (!(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");
-#ifndef FREETDS_PRE_0_62
- tds_set_client_charset(login, charset);
-#endif
- tds_set_language(login, language);
- tds_set_packet(login, 512);
- tds_set_version(login, 7, 0);
-
-#ifdef FREETDS_0_64
- if (!(context = tds_alloc_context(NULL)))
-#else
- if (!(context = tds_alloc_context()))
-#endif
- {
- ast_log(LOG_ERROR, "tds_alloc_context() failed.\n");
- goto connect_fail;
- }
-
- if (!(tds = tds_alloc_socket(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);
- if (!connection)
- {
- ast_log(LOG_ERROR, "tds_read_config() failed.\n");
- goto connect_fail;
- }
-
- if (tds_connect(tds, connection) == TDS_FAIL)
- {
- ast_log(LOG_ERROR, "Failed to connect to MSSQL server.\n");
- tds = NULL; /* freed by tds_connect() on error */
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- tds_free_connection(connection);
-#else
- tds_free_connect(connection);
-#endif
- connection = NULL;
- goto connect_fail;
- }
-#if (defined(FREETDS_0_63) || defined(FREETDS_0_64))
- tds_free_connection(connection);
-#else
- tds_free_connect(connection);
-#endif
- connection = NULL;
-
- snprintf(query, sizeof(query), "USE %s", 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))
-#else
- if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
-#endif
- {
- ast_log(LOG_ERROR, "Could not change database (%s)\n", dbname);
- goto connect_fail;
- }
-
- snprintf(query, sizeof(query), "SELECT 1 FROM %s", table);
-#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))
-#else
- if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
-#endif
- {
- ast_log(LOG_ERROR, "Could not find table '%s' in database '%s'\n", table, dbname);
- goto connect_fail;
- }
-
- has_userfield = 1;
- snprintf(query, sizeof(query), "SELECT userfield FROM %s WHERE 1 = 0", table);
-#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))
-#else
- if ((tds_submit_query(tds, query) != TDS_SUCCEED) || (tds_process_simple_query(tds) != TDS_SUCCEED))
-#endif
- {
- ast_log(LOG_NOTICE, "Unable to find 'userfield' column in table '%s'\n", table);
- has_userfield = 0;
- }
-
- connected = 1;
- return 0;
-
-connect_fail:
- mssql_disconnect();
- return -1;
-}
-
-static int tds_unload_module(void)
-{
- mssql_disconnect();
-
- ast_cdr_unregister(name);
-
- if (hostname) free(hostname);
- if (dbname) free(dbname);
- if (dbuser) free(dbuser);
- if (password) free(password);
- if (charset) free(charset);
- if (language) free(language);
- if (table) free(table);
-
- return 0;
-}
-
-static int tds_load_module(void)
-{
- int res = 0;
- struct ast_config *cfg;
- struct ast_variable *var;
- const char *ptr = NULL;
-#ifdef FREETDS_PRE_0_62
- TDS_INT result_type;
-#endif
-
- cfg = ast_config_load(config);
- if (!cfg) {
- ast_log(LOG_NOTICE, "Unable to load config for MSSQL CDR's: %s\n", config);
- return 0;
- }
-
- var = ast_variable_browse(cfg, "global");
- if (!var) /* nothing configured */ {
- ast_config_destroy(cfg);
- return 0;
- }
-
- ptr = ast_variable_retrieve(cfg, "global", "hostname");
- if (ptr)
- hostname = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database server hostname not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "dbname");
- if (ptr)
- dbname = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database dbname not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "user");
- if (ptr)
- dbuser = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database dbuser not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "password");
- if (ptr)
- password = strdup(ptr);
- else
- ast_log(LOG_ERROR,"Database password not specified.\n");
-
- ptr = ast_variable_retrieve(cfg, "global", "charset");
- if (ptr)
- charset = strdup(ptr);
- else
- charset = strdup("iso_1");
-
- ptr = ast_variable_retrieve(cfg, "global", "language");
- if (ptr)
- language = strdup(ptr);
- else
- language = strdup("us_english");
-
- ptr = ast_variable_retrieve(cfg,"global","table");
- if (ptr == NULL) {
- ast_log(LOG_DEBUG,"cdr_tds: table not specified. Assuming cdr\n");
- ptr = "cdr";
- }
- table = strdup(ptr);
-
- ast_config_destroy(cfg);
-
- mssql_connect();
-
- /* Register MSSQL CDR handler */
- res = ast_cdr_register(name, ast_module_info->description, tds_log);
- if (res)
- {
- ast_log(LOG_ERROR, "Unable to register MSSQL CDR handling\n");
- }
-
- return res;
-}
-
-static int reload(void)
-{
- tds_unload_module();
- return tds_load_module();
-}
-
-static int load_module(void)
-{
- if(!tds_load_module())
- return AST_MODULE_LOAD_DECLINE;
- else
- return AST_MODULE_LOAD_SUCCESS;
-}
-
-static int unload_module(void)
-{
- return tds_unload_module();
-}
-
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "MSSQL CDR Backend",
- .load = load_module,
- .unload = unload_module,
- .reload = reload,
- );