Asterisk - The Open Source Telephony Project GIT-master-27fb039
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Macros | Functions | Variables
cdr_csv.c File Reference

Comma Separated Value CDR records. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/config.h"
#include "asterisk/channel.h"
#include "asterisk/cdr.h"
#include "asterisk/module.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
Include dependency graph for cdr_csv.c:

Go to the source code of this file.

Macros

#define CSV_LOG_DIR   "/cdr-csv"
 
#define CSV_MASTER   "/Master.csv"
 
#define DATE_FORMAT   "%Y-%m-%d %T"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static int append_date (char *buf, struct timeval when, size_t bufsize)
 
static int append_int (char *buf, int s, size_t bufsize)
 
static int append_string (char *buf, const char *s, size_t bufsize)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int build_csv_record (char *buf, size_t bufsize, struct ast_cdr *cdr)
 
static int csv_log (struct ast_cdr *cdr)
 
static int load_config (int reload)
 
static int load_module (void)
 
static int reload (void)
 
static int unload_module (void)
 
static int writefile (char *s, char *file_path)
 
static int writefile_account (char *s, char *acc)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Comma Separated Values CDR Backend" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
 
static int accountlogs = 1
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const char config [] = "cdr.conf"
 
static ast_mutex_t f_lock = AST_MUTEX_INIT_VALUE
 
static char file_csv_master [PATH_MAX]
 
static int loaded = 0
 
static int loguniqueid = 0
 
static int loguserfield = 0
 
static char * name = "csv"
 
static int newcdrcolumns = 0
 
static int usegmtime = 0
 

Detailed Description

Comma Separated Value CDR records.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file cdr_csv.c.

Macro Definition Documentation

◆ CSV_LOG_DIR

#define CSV_LOG_DIR   "/cdr-csv"

Definition at line 49 of file cdr_csv.c.

◆ CSV_MASTER

#define CSV_MASTER   "/Master.csv"

Definition at line 50 of file cdr_csv.c.

◆ DATE_FORMAT

#define DATE_FORMAT   "%Y-%m-%d %T"

Definition at line 52 of file cdr_csv.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 364 of file cdr_csv.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 364 of file cdr_csv.c.

◆ append_date()

static int append_date ( char *  buf,
struct timeval  when,
size_t  bufsize 
)
static

Definition at line 192 of file cdr_csv.c.

193{
194 char tmp[80] = "";
195 struct ast_tm tm;
196
197 if (strlen(buf) > bufsize - 3)
198 return -1;
199
200 if (ast_tvzero(when)) {
201 strncat(buf, ",", bufsize - strlen(buf) - 1);
202 return 0;
203 }
204
205 ast_localtime(&when, &tm, usegmtime ? "GMT" : NULL);
206 ast_strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
207
208 return append_string(buf, tmp, bufsize);
209}
static int append_string(char *buf, const char *s, size_t bufsize)
Definition cdr_csv.c:147
static int usegmtime
Definition cdr_csv.c:54
#define DATE_FORMAT
Definition cdr_csv.c:52
char buf[BUFSIZE]
Definition eagi_proxy.c:66
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
Definition localtime.c:1739
int ast_strftime(char *buf, size_t len, const char *format, const struct ast_tm *tm)
Special version of strftime(3) that handles fractions of a second. Takes the same arguments as strfti...
Definition localtime.c:2524
#define NULL
Definition resample.c:96
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition time.h:117

References append_string(), ast_localtime(), ast_strftime(), ast_tvzero(), buf, DATE_FORMAT, NULL, and usegmtime.

Referenced by build_csv_record().

◆ append_int()

static int append_int ( char *  buf,
int  s,
size_t  bufsize 
)
static

Definition at line 174 of file cdr_csv.c.

175{
176 char tmp[32];
177 int pos = strlen(buf);
178
179 snprintf(tmp, sizeof(tmp), "%d", s);
180
181 if (pos + strlen(tmp) > bufsize - 3)
182 return -1;
183
184 strncat(buf, tmp, bufsize - strlen(buf) - 1);
185 pos = strlen(buf);
186 buf[pos++] = ',';
187 buf[pos++] = '\0';
188
189 return 0;
190}

References buf.

Referenced by build_csv_record().

◆ append_string()

static int append_string ( char *  buf,
const char *  s,
size_t  bufsize 
)
static

Definition at line 147 of file cdr_csv.c.

148{
149 int pos = strlen(buf), spos = 0, error = -1;
150
151 if (pos >= bufsize - 4)
152 return -1;
153
154 buf[pos++] = '\"';
155
156 while(pos < bufsize - 3) {
157 if (!s[spos]) {
158 error = 0;
159 break;
160 }
161 if (s[spos] == '\"')
162 buf[pos++] = '\"';
163 buf[pos++] = s[spos];
164 spos++;
165 }
166
167 buf[pos++] = '\"';
168 buf[pos++] = ',';
169 buf[pos++] = '\0';
170
171 return error;
172}
int error(const char *format,...)

References buf, and error().

Referenced by append_date(), and build_csv_record().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 364 of file cdr_csv.c.

◆ build_csv_record()

static int build_csv_record ( char *  buf,
size_t  bufsize,
struct ast_cdr cdr 
)
static

Definition at line 211 of file cdr_csv.c.

212{
213
214 buf[0] = '\0';
215 /* Account code */
216 append_string(buf, cdr->accountcode, bufsize);
217 /* Source */
218 append_string(buf, cdr->src, bufsize);
219 /* Destination */
220 append_string(buf, cdr->dst, bufsize);
221 /* Destination context */
222 append_string(buf, cdr->dcontext, bufsize);
223 /* Caller*ID */
224 append_string(buf, cdr->clid, bufsize);
225 /* Channel */
226 append_string(buf, cdr->channel, bufsize);
227 /* Destination Channel */
228 append_string(buf, cdr->dstchannel, bufsize);
229 /* Last Application */
230 append_string(buf, cdr->lastapp, bufsize);
231 /* Last Data */
232 append_string(buf, cdr->lastdata, bufsize);
233 /* Start Time */
234 append_date(buf, cdr->start, bufsize);
235 /* Answer Time */
236 append_date(buf, cdr->answer, bufsize);
237 /* End Time */
238 append_date(buf, cdr->end, bufsize);
239 /* Duration */
240 append_int(buf, cdr->duration, bufsize);
241 /* Billable seconds */
242 append_int(buf, cdr->billsec, bufsize);
243 /* Disposition */
245 /* AMA Flags */
247 /* Unique ID */
248 if (loguniqueid)
249 append_string(buf, cdr->uniqueid, bufsize);
250 /* append the user field */
251 if(loguserfield)
252 append_string(buf, cdr->userfield, bufsize);
253 if (newcdrcolumns) {
254 append_string(buf, cdr->peeraccount, bufsize);
255 append_string(buf, cdr->linkedid, bufsize);
256 append_int(buf, cdr->sequence, bufsize);
257 }
258 /* If we hit the end of our buffer, log an error */
259 if (strlen(buf) < bufsize - 5) {
260 /* Trim off trailing comma */
261 buf[strlen(buf) - 1] = '\0';
262 strncat(buf, "\n", bufsize - strlen(buf) - 1);
263 return 0;
264 }
265 return -1;
266}
const char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition cdr.c:3576
static int append_date(char *buf, struct timeval when, size_t bufsize)
Definition cdr_csv.c:192
static int loguserfield
Definition cdr_csv.c:57
static int loguniqueid
Definition cdr_csv.c:56
static int append_int(char *buf, int s, size_t bufsize)
Definition cdr_csv.c:174
static int newcdrcolumns
Definition cdr_csv.c:59
const char * ast_channel_amaflags2string(enum ama_flags flags)
Convert the enum representation of an AMA flag to a string representation.
Definition channel.c:4367
char dstchannel[AST_MAX_EXTENSION]
Definition cdr.h:293
long int disposition
Definition cdr.h:309
char lastdata[AST_MAX_EXTENSION]
Definition cdr.h:297
char linkedid[AST_MAX_UNIQUEID]
Definition cdr.h:321
char userfield[AST_MAX_USER_FIELD]
Definition cdr.h:327
long int billsec
Definition cdr.h:307
struct timeval answer
Definition cdr.h:301
char channel[AST_MAX_EXTENSION]
Definition cdr.h:291
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition cdr.h:315
long int duration
Definition cdr.h:305
long int amaflags
Definition cdr.h:311
char src[AST_MAX_EXTENSION]
Definition cdr.h:285
char dst[AST_MAX_EXTENSION]
Definition cdr.h:287
char clid[AST_MAX_EXTENSION]
Definition cdr.h:283
char uniqueid[AST_MAX_UNIQUEID]
Definition cdr.h:319
int sequence
Definition cdr.h:329
struct timeval start
Definition cdr.h:299
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition cdr.h:313
char lastapp[AST_MAX_EXTENSION]
Definition cdr.h:295
char dcontext[AST_MAX_EXTENSION]
Definition cdr.h:289
struct timeval end
Definition cdr.h:303

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, append_date(), append_int(), append_string(), ast_cdr_disp2str(), ast_channel_amaflags2string(), ast_cdr::billsec, buf, ast_cdr::channel, ast_cdr::clid, ast_cdr::dcontext, ast_cdr::disposition, ast_cdr::dst, ast_cdr::dstchannel, ast_cdr::duration, ast_cdr::end, ast_cdr::lastapp, ast_cdr::lastdata, ast_cdr::linkedid, loguniqueid, loguserfield, newcdrcolumns, ast_cdr::peeraccount, ast_cdr::sequence, ast_cdr::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by csv_log().

◆ csv_log()

static int csv_log ( struct ast_cdr cdr)
static

Definition at line 297 of file cdr_csv.c.

298{
299 /* Make sure we have a big enough buf */
300 char buf[1024];
301 if (build_csv_record(buf, sizeof(buf), cdr)) {
302 ast_log(LOG_WARNING, "Unable to create CSV record in %d bytes. CDR not recorded!\n", (int)sizeof(buf));
303 return 0;
304 }
305
308 ast_log(LOG_WARNING, "Unable to write CSV record to master '%s' : %s\n", file_csv_master, strerror(errno));
309
312 ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno));
313 }
315 return 0;
316}
#define ast_log
Definition astobj2.c:42
static int writefile_account(char *s, char *acc)
Definition cdr_csv.c:286
static int writefile(char *s, char *file_path)
Definition cdr_csv.c:268
static int accountlogs
Definition cdr_csv.c:55
static ast_mutex_t f_lock
Definition cdr_csv.c:96
static char file_csv_master[PATH_MAX]
Definition cdr_csv.c:61
static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
Definition cdr_csv.c:211
#define LOG_WARNING
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196
int errno
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65

References ast_cdr::accountcode, accountlogs, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), buf, build_csv_record(), errno, f_lock, file_csv_master, LOG_WARNING, writefile(), and writefile_account().

Referenced by load_module().

◆ load_config()

static int load_config ( int  reload)
static

Definition at line 98 of file cdr_csv.c.

99{
100 struct ast_config *cfg;
101 struct ast_variable *v;
102 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
103
104 if (!(cfg = ast_config_load(config, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
105 ast_log(LOG_WARNING, "unable to load config: %s\n", config);
106 return 0;
107 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
108 return 1;
109 }
110
111 accountlogs = 1;
112 usegmtime = 0;
113 loguniqueid = 0;
114 loguserfield = 0;
115 newcdrcolumns = 0;
116
117 if (!(v = ast_variable_browse(cfg, "csv"))) {
119 return 0;
120 }
121
122 /* compute the location of the csv master file */
124 snprintf(file_csv_master, sizeof(file_csv_master),
127
128 for (; v; v = v->next) {
129 if (!strcasecmp(v->name, "usegmtime")) {
131 } else if (!strcasecmp(v->name, "accountlogs")) {
132 /* Turn on/off separate files per accountcode. Default is on (as before) */
134 } else if (!strcasecmp(v->name, "loguniqueid")) {
136 } else if (!strcasecmp(v->name, "loguserfield")) {
138 } else if (!strcasecmp(v->name, "newcdrcolumns")) {
140 }
141
142 }
144 return 1;
145}
#define CSV_MASTER
Definition cdr_csv.c:50
#define CSV_LOG_DIR
Definition cdr_csv.c:49
static const char config[]
Definition cdr_csv.c:60
static int reload(void)
Definition cdr_csv.c:344
#define ast_config_load(filename, flags)
Load a config file.
#define CONFIG_STATUS_FILEUNCHANGED
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
Definition extconf.c:1287
@ CONFIG_FLAG_FILEUNCHANGED
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition extconf.c:1213
const char * ast_config_AST_LOG_DIR
Definition options.c:160
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
Definition utils.c:2235
Structure used to handle boolean flags.
Definition utils.h:220
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next

References accountlogs, ast_config_AST_LOG_DIR, ast_config_destroy(), ast_config_load, ast_log, ast_mutex_lock, ast_mutex_unlock, ast_true(), ast_variable_browse(), config, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, CSV_LOG_DIR, CSV_MASTER, f_lock, file_csv_master, LOG_WARNING, loguniqueid, loguserfield, ast_variable::name, newcdrcolumns, ast_variable::next, reload(), usegmtime, and ast_variable::value.

◆ load_module()

static int load_module ( void  )
static

Definition at line 328 of file cdr_csv.c.

329{
330 int res;
331
332 if (!load_config(0)) {
334 }
335
337 ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
338 } else {
339 loaded = 1;
340 }
341 return res;
342}
static int load_config(void)
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition cdr.c:3076
static int csv_log(struct ast_cdr *cdr)
Definition cdr_csv.c:297
static int loaded
Definition cdr_csv.c:58
static char * name
Definition cdr_csv.c:94
#define LOG_ERROR
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78
const char * description
Definition module.h:366

References ast_cdr_register(), ast_log, AST_MODULE_LOAD_DECLINE, csv_log(), ast_module_info::description, load_config(), loaded, LOG_ERROR, and name.

◆ reload()

static int reload ( void  )
static

Definition at line 344 of file cdr_csv.c.

345{
346 if (load_config(1)) {
347 loaded = 1;
348 } else {
349 loaded = 0;
350 ast_log(LOG_WARNING, "No [csv] section in cdr.conf. Unregistering backend.\n");
352 }
353
354 return 0;
355}
int ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition cdr.c:3121

References ast_cdr_unregister(), ast_log, load_config(), loaded, LOG_WARNING, and name.

Referenced by load_config().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 318 of file cdr_csv.c.

319{
321 return -1;
322 }
323
324 loaded = 0;
325 return 0;
326}

References ast_cdr_unregister(), loaded, and name.

◆ writefile()

static int writefile ( char *  s,
char *  file_path 
)
static

Definition at line 268 of file cdr_csv.c.

269{
270 FILE *f;
271 /* because of the absolutely unconditional need for the
272 highest reliability possible in writing billing records,
273 we open write and close the log file each time */
274 if (!(f = fopen(file_path, "a"))) {
275 ast_log(LOG_ERROR, "Unable to open file %s : %s\n", file_path, strerror(errno));
276 return -1;
277 }
278 fputs(s, f);
279 fflush(f); /* be particularly anal here */
280 fclose(f);
281
282 return 0;
283}

References ast_log, errno, and LOG_ERROR.

Referenced by csv_log(), and writefile_account().

◆ writefile_account()

static int writefile_account ( char *  s,
char *  acc 
)
static

Definition at line 286 of file cdr_csv.c.

287{
288 char file_account[PATH_MAX];
289 if (strchr(acc, '/') || (acc[0] == '.')) {
290 ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
291 return -1;
292 }
293 snprintf(file_account, sizeof(file_account), "%s/%s/%s.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
294 return writefile(s, file_account);
295}
#define PATH_MAX
Definition asterisk.h:40

References ast_config_AST_LOG_DIR, ast_log, CSV_LOG_DIR, LOG_WARNING, PATH_MAX, and writefile().

Referenced by csv_log().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Comma Separated Values CDR Backend" , .key = ASTERISK_GPL_KEY , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_EXTENDED, .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, .requires = "cdr", }
static

Definition at line 364 of file cdr_csv.c.

◆ accountlogs

int accountlogs = 1
static

Definition at line 55 of file cdr_csv.c.

Referenced by csv_log(), and load_config().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 364 of file cdr_csv.c.

◆ config

const char config[] = "cdr.conf"
static

Definition at line 60 of file cdr_csv.c.

Referenced by load_config().

◆ f_lock

Definition at line 96 of file cdr_csv.c.

Referenced by csv_log(), and load_config().

◆ file_csv_master

char file_csv_master[PATH_MAX]
static

Definition at line 61 of file cdr_csv.c.

Referenced by csv_log(), and load_config().

◆ loaded

int loaded = 0
static

Definition at line 58 of file cdr_csv.c.

Referenced by load_module(), load_or_reload_lua_stuff(), reload(), and unload_module().

◆ loguniqueid

int loguniqueid = 0
static

Definition at line 56 of file cdr_csv.c.

Referenced by build_csv_record(), and load_config().

◆ loguserfield

int loguserfield = 0
static

Definition at line 57 of file cdr_csv.c.

Referenced by build_csv_record(), and load_config().

◆ name

char* name = "csv"
static

Definition at line 94 of file cdr_csv.c.

Referenced by load_module(), reload(), and unload_module().

◆ newcdrcolumns

int newcdrcolumns = 0
static

Definition at line 59 of file cdr_csv.c.

Referenced by build_csv_record(), and load_config().

◆ usegmtime

int usegmtime = 0
static

Definition at line 54 of file cdr_csv.c.

Referenced by append_date(), load_config(), and load_config().