00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <sys/types.h>
00032 #include <stdio.h>
00033 #include <string.h>
00034 #include <errno.h>
00035
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <time.h>
00039
00040 #include "asterisk.h"
00041
00042 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 7221 $")
00043
00044 #include "asterisk/channel.h"
00045 #include "asterisk/cdr.h"
00046 #include "asterisk/module.h"
00047 #include "asterisk/config.h"
00048 #include "asterisk/pbx.h"
00049 #include "asterisk/logger.h"
00050 #include "asterisk/utils.h"
00051
00052 #define CUSTOM_LOG_DIR "/cdr_custom"
00053
00054 #define DATE_FORMAT "%Y-%m-%d %T"
00055
00056 AST_MUTEX_DEFINE_STATIC(lock);
00057
00058 static char *desc = "Customizable Comma Separated Values CDR Backend";
00059
00060 static char *name = "cdr-custom";
00061
00062 static FILE *mf = NULL;
00063
00064 static char master[AST_CONFIG_MAX_PATH];
00065 static char format[1024]="";
00066
00067 static int load_config(int reload)
00068 {
00069 struct ast_config *cfg;
00070 struct ast_variable *var;
00071 int res = -1;
00072
00073 strcpy(format, "");
00074 strcpy(master, "");
00075 if((cfg = ast_config_load("cdr_custom.conf"))) {
00076 var = ast_variable_browse(cfg, "mappings");
00077 while(var) {
00078 ast_mutex_lock(&lock);
00079 if (!ast_strlen_zero(var->name) && !ast_strlen_zero(var->value)) {
00080 if (strlen(var->value) > (sizeof(format) - 2))
00081 ast_log(LOG_WARNING, "Format string too long, will be truncated, at line %d\n", var->lineno);
00082 strncpy(format, var->value, sizeof(format) - 2);
00083 strcat(format,"\n");
00084 snprintf(master, sizeof(master),"%s/%s/%s", ast_config_AST_LOG_DIR, name, var->name);
00085 ast_mutex_unlock(&lock);
00086 } else
00087 ast_log(LOG_NOTICE, "Mapping must have both filename and format at line %d\n", var->lineno);
00088 if (var->next)
00089 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);
00090 var = var->next;
00091 }
00092 ast_config_destroy(cfg);
00093 res = 0;
00094 } else {
00095 if (reload)
00096 ast_log(LOG_WARNING, "Failed to reload configuration file.\n");
00097 else
00098 ast_log(LOG_WARNING, "Failed to load configuration file. Module not activated.\n");
00099 }
00100
00101 return res;
00102 }
00103
00104
00105
00106 static int custom_log(struct ast_cdr *cdr)
00107 {
00108
00109 char buf[2048];
00110 struct ast_channel dummy;
00111
00112
00113 if (ast_strlen_zero(master))
00114 return 0;
00115
00116 memset(buf, 0 , sizeof(buf));
00117
00118 memset(&dummy, 0, sizeof(dummy));
00119 dummy.cdr = cdr;
00120 pbx_substitute_variables_helper(&dummy, format, buf, sizeof(buf) - 1);
00121
00122
00123
00124
00125 mf = fopen(master, "a");
00126 if (!mf) {
00127 ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", master, strerror(errno));
00128 }
00129 if (mf) {
00130 fputs(buf, mf);
00131 fflush(mf);
00132 fclose(mf);
00133 mf = NULL;
00134 }
00135 return 0;
00136 }
00137
00138 char *description(void)
00139 {
00140 return desc;
00141 }
00142
00143 int unload_module(void)
00144 {
00145 if (mf)
00146 fclose(mf);
00147 ast_cdr_unregister(name);
00148 return 0;
00149 }
00150
00151 int load_module(void)
00152 {
00153 int res = 0;
00154
00155 if (!load_config(0)) {
00156 res = ast_cdr_register(name, desc, custom_log);
00157 if (res)
00158 ast_log(LOG_ERROR, "Unable to register custom CDR handling\n");
00159 if (mf)
00160 fclose(mf);
00161 }
00162 return res;
00163 }
00164
00165 int reload(void)
00166 {
00167 return load_config(1);
00168 }
00169
00170 int usecount(void)
00171 {
00172 return 0;
00173 }
00174
00175 char *key()
00176 {
00177 return ASTERISK_GPL_KEY;
00178 }