[svn-commits] juggie: branch juggie/NoLossCDR r83022 - in /team/juggie/NoLossCDR: cdr/ conf...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Tue Sep 18 20:49:40 CDT 2007
Author: juggie
Date: Tue Sep 18 20:49:39 2007
New Revision: 83022
URL: http://svn.digium.com/view/asterisk?view=rev&rev=83022
Log:
Adds the ability to specify more than a single mapping in cdr_custom and updates cdr_custom.conf.sample to demonstrate. bug#: 10747
Modified:
team/juggie/NoLossCDR/cdr/cdr_custom.c
team/juggie/NoLossCDR/configs/cdr_custom.conf.sample
team/juggie/NoLossCDR/main/cdr.c
Modified: team/juggie/NoLossCDR/cdr/cdr_custom.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/cdr/cdr_custom.c?view=diff&rev=83022&r1=83021&r2=83022
==============================================================================
--- team/juggie/NoLossCDR/cdr/cdr_custom.c (original)
+++ team/juggie/NoLossCDR/cdr/cdr_custom.c Tue Sep 18 20:49:39 2007
@@ -51,44 +51,82 @@
#include "asterisk/logger.h"
#include "asterisk/utils.h"
-#define CUSTOM_LOG_DIR "/cdr_custom"
-
-#define DATE_FORMAT "%Y-%m-%d %T"
+#define CUSTOM_LOG_DIR "cdr-custom"
+
+#define DATE_FORMAT "%Y-%m-%d %T"
+#define FORMAT_MAX 1024
+#define DEFAULT_BUFFER_SIZE 2048
AST_MUTEX_DEFINE_STATIC(lock);
static char *name = "cdr-custom";
-static FILE *mf = NULL;
-
-static char master[PATH_MAX];
-static char format[1024]="";
+struct cdr_custom_sink
+{
+ char filename[PATH_MAX];
+ char format[FORMAT_MAX];
+
+ FILE *output;
+};
+
+/* Prototypes */
+static int custom_log(struct ast_cdr *cdr, void *data);
+
+static void free_config(void *data)
+{
+ struct cdr_custom_sink *sink = (struct cdr_custom_sink *) data;
+
+ if (!sink)
+ return;
+
+ if (sink->output)
+ fclose(sink->output);
+
+ ast_free(sink);
+}
static int load_config(int reload)
{
struct ast_config *cfg;
struct ast_variable *var;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+ struct cdr_custom_sink *sink = NULL;
int res = -1;
if ((cfg = ast_config_load("cdr_custom.conf", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
return 0;
- strcpy(format, "");
- strcpy(master, "");
+ if (reload)
+ ast_cdr_unregister(name, NULL);
+
ast_mutex_lock(&lock);
if (cfg) {
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))
+ if (strlen(var->value) > (FORMAT_MAX - 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);
+ sink = (struct cdr_custom_sink *) ast_calloc(1, sizeof(struct cdr_custom_sink));
+ if (!sink) {
+ ast_log(LOG_ERROR, "Unable to allocate CDR custom configuration.\n");
break;
+ }
+ ast_copy_string(sink->format, var->value, FORMAT_MAX - 1);
+ strcat(sink->format, "\n");
+ snprintf(sink->filename, PATH_MAX, "%s/%s/%s", ast_config_AST_LOG_DIR, CUSTOM_LOG_DIR, var->name);
+ /* Try to open the file */
+ sink->output = fopen(sink->filename, "a");
+ if (!sink->output) {
+ ast_log(LOG_ERROR, "Unable to open CDR log file \"%s\": %s\n", sink->filename, strerror(errno));
+ ast_free(sink);
+ } else {
+ fclose(sink->output);
+ sink->output = NULL;
+ res = ast_cdr_register(name, var->name, ast_module_info->description, custom_log, free_config, sink);
+ if (res) {
+ ast_log(LOG_ERROR, "Failed to register CDR custom handler sink \"%s\" at line %d\n", var->name, var->lineno);
+ ast_free(sink);
+ }
}
} else
ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
@@ -107,62 +145,53 @@
return res;
}
-
-
static int custom_log(struct ast_cdr *cdr, void *data)
{
/* Make sure we have a big enough buf */
- char buf[2048];
+ char buf[DEFAULT_BUFFER_SIZE];
struct ast_channel dummy;
+ struct cdr_custom_sink *sink = (struct cdr_custom_sink *) data;
/* Abort if no master file is specified */
- if (ast_strlen_zero(master))
+ if (ast_strlen_zero(sink->filename))
return 0;
- memset(buf, 0 , sizeof(buf));
+ memset(buf, 0 , DEFAULT_BUFFER_SIZE);
/* 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);
+ pbx_substitute_variables_helper(&dummy, sink->format, buf, DEFAULT_BUFFER_SIZE - 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 */
- mf = fopen(master, "a");
- if (!mf) {
- ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
+ sink->output = fopen(sink->filename, "a");
+ if (!sink->output) {
+ ast_log(LOG_ERROR, "Unable to re-open CDR custom file %s : %s\n", sink->filename, strerror(errno));
return AST_CDR_POST_RETRY;
+ } else {
+ fputs(buf, sink->output);
+ fflush(sink->output); /* be particularly anal here */
+ fclose(sink->output);
+ sink->output = NULL;
}
- if (mf) {
- fputs(buf, mf);
- fflush(mf); /* be particularly anal here */
- fclose(mf);
- mf = NULL;
- }
+
return AST_CDR_POST_OK;
}
static int unload_module(void)
{
- if (mf)
- fclose(mf);
ast_cdr_unregister(name, NULL);
+
return 0;
}
static int load_module(void)
{
- int res = 0;
-
- if (!load_config(0)) {
- res = ast_cdr_register(name, NULL, ast_module_info->description, custom_log, NULL, NULL);
- if (res)
- ast_log(LOG_ERROR, "Unable to register custom CDR handling\n");
- if (mf)
- fclose(mf);
- return res;
- } else
- return AST_MODULE_LOAD_DECLINE;
+ if (!load_config(0))
+ return AST_MODULE_LOAD_SUCCESS;
+
+ return AST_MODULE_LOAD_DECLINE;
}
static int reload(void)
Modified: team/juggie/NoLossCDR/configs/cdr_custom.conf.sample
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/configs/cdr_custom.conf.sample?view=diff&rev=83022&r1=83021&r2=83022
==============================================================================
--- team/juggie/NoLossCDR/configs/cdr_custom.conf.sample (original)
+++ team/juggie/NoLossCDR/configs/cdr_custom.conf.sample Tue Sep 18 20:49:39 2007
@@ -4,7 +4,8 @@
; to get your csv output in a format tailored to your liking, uncomment the following
; and look for the output in the cdr-custom/Master.csv file (usually in /var/log/asterisk).
;
-;
+
;[mappings]
;Master.csv => "${CDR(clid)}","${CDR(src)}","${CDR(dst)}","${CDR(dcontext)}","${CDR(channel)}","${CDR(dstchannel)}","${CDR(lastapp)}","${CDR(lastdata)}","${CDR(start)}","${CDR(answer)}","${CDR(end)}","${CDR(duration)}","${CDR(billsec)}","${CDR(disposition)}","${CDR(amaflags)}","${CDR(accountcode)}","${CDR(uniqueid)}","${CDR(userfield)}"
+;MasterSimple.csv => "${CDR(src)}","${CDR(dst)}"
Modified: team/juggie/NoLossCDR/main/cdr.c
URL: http://svn.digium.com/view/asterisk/team/juggie/NoLossCDR/main/cdr.c?view=diff&rev=83022&r1=83021&r2=83022
==============================================================================
--- team/juggie/NoLossCDR/main/cdr.c (original)
+++ team/juggie/NoLossCDR/main/cdr.c Tue Sep 18 20:49:39 2007
@@ -118,7 +118,7 @@
}
}
- if (!(i = ast_calloc(1, sizeof(*i))))
+ if (!(i = ast_calloc(1, sizeof(struct ast_cdr_beitem))))
return -1;
i->be = be;
@@ -146,25 +146,25 @@
/*! unregister a CDR driver */
void ast_cdr_unregister(const char *name, const char *name_detail)
{
- struct ast_cdr_beitem *i = NULL;
+ struct ast_cdr_beitem *item = NULL;
AST_RWLIST_WRLOCK(&be_list);
- AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, i, list) {
- if (!strcasecmp(name, i->name) && (!name_detail || !strcasecmp(name_detail, i->name_detail))) {
- i->cancel_thread = 1;
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&be_list, item, list) {
+ if (!strcasecmp(name, item->name) && (!name_detail || !strcasecmp(name_detail, item->name_detail))) {
+ item->cancel_thread = 1;
/* signal the thread so it can exit */
- ast_cond_signal(&i->cdr_pending_cond);
+ ast_cond_signal(&item->cdr_pending_cond);
/* wait for thread to exit so we can clean up */
- pthread_join(i->cdr_thread, NULL);
- i->cdr_thread = AST_PTHREADT_NULL;
- ast_cond_destroy(&i->cdr_pending_cond);
- ast_cond_destroy(&i->cdr_retry_cond);
+ pthread_join(item->cdr_thread, NULL);
+ item->cdr_thread = AST_PTHREADT_NULL;
+ ast_cond_destroy(&item->cdr_pending_cond);
+ ast_cond_destroy(&item->cdr_retry_cond);
AST_RWLIST_REMOVE_CURRENT(&be_list, list);
if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s - %s' CDR backend\n", i->name, i->name_detail);
- if (i->cleanup)
- i->cleanup(i->be_data);
- ast_free(i);
+ ast_verbose(VERBOSE_PREFIX_2 "Unregistered '%s - %s' CDR backend\n", item->name, item->name_detail);
+ if (item->cleanup)
+ item->cleanup(item->be_data);
+ ast_free(item);
if (name_detail)
break;
}
More information about the svn-commits
mailing list