[asterisk-commits] juggie: branch juggie/NoLossCDR r83022 - in /team/juggie/NoLossCDR: cdr/ conf...

SVN commits to the Asterisk project asterisk-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 asterisk-commits mailing list