Wed Jan 8 2020 09:49:59

Asterisk developer's documentation


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"

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)
 
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 *acc)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Comma Separated Values CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, }
 
static int accountlogs
 
static ast_mutex_t acf_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static const char config [] = "cdr.conf"
 
static int loaded = 0
 
static int loguniqueid = 0
 
static int loguserfield = 0
 
static ast_mutex_t mf_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static char * name = "csv"
 
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

#define CSV_LOG_DIR   "/cdr-csv"

Definition at line 47 of file cdr_csv.c.

Referenced by csv_log(), and writefile().

#define CSV_MASTER   "/Master.csv"

Definition at line 48 of file cdr_csv.c.

Referenced by csv_log().

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

Definition at line 50 of file cdr_csv.c.

Referenced by append_date().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 369 of file cdr_csv.c.

static void __unreg_module ( void  )
static

Definition at line 369 of file cdr_csv.c.

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

Definition at line 193 of file cdr_csv.c.

References append_string(), ast_localtime(), ast_strftime(), ast_tvzero(), and DATE_FORMAT.

Referenced by build_csv_record().

194 {
195  char tmp[80] = "";
196  struct ast_tm tm;
197 
198  if (strlen(buf) > bufsize - 3)
199  return -1;
200 
201  if (ast_tvzero(when)) {
202  strncat(buf, ",", bufsize - strlen(buf) - 1);
203  return 0;
204  }
205 
206  ast_localtime(&when, &tm, usegmtime ? "GMT" : NULL);
207  ast_strftime(tmp, sizeof(tmp), DATE_FORMAT, &tm);
208 
209  return append_string(buf, tmp, bufsize);
210 }
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:1570
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
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:2351
#define DATE_FORMAT
Definition: cdr_csv.c:50
static int append_string(char *buf, const char *s, size_t bufsize)
Definition: cdr_csv.c:148
static int usegmtime
Definition: cdr_csv.c:52
static int append_int ( char *  buf,
int  s,
size_t  bufsize 
)
static

Definition at line 175 of file cdr_csv.c.

Referenced by build_csv_record().

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

Definition at line 148 of file cdr_csv.c.

Referenced by append_date(), and build_csv_record().

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

Definition at line 212 of file cdr_csv.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr::answer, append_date(), append_int(), append_string(), ast_cdr_disp2str(), ast_cdr_flags2str(), ast_cdr::billsec, 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::src, ast_cdr::start, ast_cdr::uniqueid, and ast_cdr::userfield.

Referenced by csv_log().

213 {
214 
215  buf[0] = '\0';
216  /* Account code */
217  append_string(buf, cdr->accountcode, bufsize);
218  /* Source */
219  append_string(buf, cdr->src, bufsize);
220  /* Destination */
221  append_string(buf, cdr->dst, bufsize);
222  /* Destination context */
223  append_string(buf, cdr->dcontext, bufsize);
224  /* Caller*ID */
225  append_string(buf, cdr->clid, bufsize);
226  /* Channel */
227  append_string(buf, cdr->channel, bufsize);
228  /* Destination Channel */
229  append_string(buf, cdr->dstchannel, bufsize);
230  /* Last Application */
231  append_string(buf, cdr->lastapp, bufsize);
232  /* Last Data */
233  append_string(buf, cdr->lastdata, bufsize);
234  /* Start Time */
235  append_date(buf, cdr->start, bufsize);
236  /* Answer Time */
237  append_date(buf, cdr->answer, bufsize);
238  /* End Time */
239  append_date(buf, cdr->end, bufsize);
240  /* Duration */
241  append_int(buf, cdr->duration, bufsize);
242  /* Billable seconds */
243  append_int(buf, cdr->billsec, bufsize);
244  /* Disposition */
245  append_string(buf, ast_cdr_disp2str(cdr->disposition), bufsize);
246  /* AMA Flags */
247  append_string(buf, ast_cdr_flags2str(cdr->amaflags), bufsize);
248  /* Unique ID */
249  if (loguniqueid)
250  append_string(buf, cdr->uniqueid, bufsize);
251  /* append the user field */
252  if(loguserfield)
253  append_string(buf, cdr->userfield,bufsize);
254  /* If we hit the end of our buffer, log an error */
255  if (strlen(buf) < bufsize - 5) {
256  /* Trim off trailing comma */
257  buf[strlen(buf) - 1] = '\0';
258  strncat(buf, "\n", bufsize - strlen(buf) - 1);
259  return 0;
260  }
261  return -1;
262 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
static int loguniqueid
Definition: cdr_csv.c:54
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:94
long int billsec
Definition: cdr.h:108
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:90
char uniqueid[150]
Definition: cdr.h:121
char * ast_cdr_flags2str(int flags)
Definition: cdr.c:977
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:98
long int amaflags
Definition: cdr.h:112
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
struct timeval answer
Definition: cdr.h:102
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:96
struct timeval start
Definition: cdr.h:100
long int duration
Definition: cdr.h:106
char src[AST_MAX_EXTENSION]
Definition: cdr.h:86
struct timeval end
Definition: cdr.h:104
static int append_string(char *buf, const char *s, size_t bufsize)
Definition: cdr_csv.c:148
static int append_int(char *buf, int s, size_t bufsize)
Definition: cdr_csv.c:175
long int disposition
Definition: cdr.h:110
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:84
char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:959
static int loguserfield
Definition: cdr_csv.c:55
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:125
static int append_date(char *buf, struct timeval when, size_t bufsize)
Definition: cdr_csv.c:193
static int csv_log ( struct ast_cdr cdr)
static

Definition at line 291 of file cdr_csv.c.

References ast_cdr::accountcode, ast_cdr::amaflags, ast_cdr_disp2str(), ast_cdr_flags2str(), ast_config_AST_LOG_DIR, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_strlen_zero(), ast_cdr::billsec, build_csv_record(), ast_cdr::channel, CSV_LOG_DIR, CSV_MASTER, ast_cdr::disposition, ast_cdr::dst, ast_cdr::duration, errno, LOG_ERROR, LOG_WARNING, mf_lock, ast_cdr::src, and writefile().

Referenced by load_module().

292 {
293  FILE *mf = NULL;
294  /* Make sure we have a big enough buf */
295  char buf[1024];
296  char csvmaster[PATH_MAX];
297  snprintf(csvmaster, sizeof(csvmaster),"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER);
298 #if 0
299  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);
300 #endif
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 
306  /* because of the absolutely unconditional need for the
307  highest reliability possible in writing billing records,
308  we open write and close the log file each time */
310  if ((mf = fopen(csvmaster, "a"))) {
311  fputs(buf, mf);
312  fflush(mf); /* be particularly anal here */
313  fclose(mf);
314  mf = NULL;
316  } else {
318  ast_log(LOG_ERROR, "Unable to re-open master file %s : %s\n", csvmaster, strerror(errno));
319  }
320 
321  if (accountlogs && !ast_strlen_zero(cdr->accountcode)) {
322  if (writefile(buf, cdr->accountcode))
323  ast_log(LOG_WARNING, "Unable to write CSV record to account file '%s' : %s\n", cdr->accountcode, strerror(errno));
324  }
325 
326  return 0;
327 }
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:114
long int billsec
Definition: cdr.h:108
#define LOG_WARNING
Definition: logger.h:144
#define CSV_MASTER
Definition: cdr_csv.c:48
#define ast_mutex_lock(a)
Definition: lock.h:155
char * ast_cdr_flags2str(int flags)
Definition: cdr.c:977
long int amaflags
Definition: cdr.h:112
static int accountlogs
Definition: cdr_csv.c:53
static ast_mutex_t mf_lock
Definition: cdr_csv.c:92
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:88
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:92
#define LOG_ERROR
Definition: logger.h:155
static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
Definition: cdr_csv.c:212
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_config_AST_LOG_DIR
Definition: asterisk.c:263
int errno
static int writefile(char *s, char *acc)
Definition: cdr_csv.c:264
long int duration
Definition: cdr.h:106
char src[AST_MAX_EXTENSION]
Definition: cdr.h:86
#define CSV_LOG_DIR
Definition: cdr_csv.c:47
long int disposition
Definition: cdr.h:110
char * ast_cdr_disp2str(int disposition)
Disposition to a string.
Definition: cdr.c:959
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int load_config ( int  reload)
static

Definition at line 95 of file cdr_csv.c.

References ast_config_destroy(), ast_config_load, ast_debug, ast_log(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, LOG_WARNING, and var.

Referenced by load_module(), and reload().

96 {
97  struct ast_config *cfg;
98  struct ast_variable *var;
99  const char *tmp;
100  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
101 
102  if (!(cfg = ast_config_load(config, config_flags)) || cfg == CONFIG_STATUS_FILEINVALID) {
103  ast_log(LOG_WARNING, "unable to load config: %s\n", config);
104  return 0;
105  } else if (cfg == CONFIG_STATUS_FILEUNCHANGED)
106  return 1;
107 
108  accountlogs = 1;
109  usegmtime = 0;
110  loguniqueid = 0;
111  loguserfield = 0;
112 
113  if (!(var = ast_variable_browse(cfg, "csv"))) {
114  ast_config_destroy(cfg);
115  return 0;
116  }
117 
118  if ((tmp = ast_variable_retrieve(cfg, "csv", "usegmtime"))) {
119  usegmtime = ast_true(tmp);
120  if (usegmtime)
121  ast_debug(1, "logging time in GMT\n");
122  }
123 
124  /* Turn on/off separate files per accountcode. Default is on (as before) */
125  if ((tmp = ast_variable_retrieve(cfg, "csv", "accountlogs"))) {
126  accountlogs = ast_true(tmp);
127  if (accountlogs) {
128  ast_debug(1, "logging in separate files per accountcode\n");
129  }
130  }
131 
132  if ((tmp = ast_variable_retrieve(cfg, "csv", "loguniqueid"))) {
133  loguniqueid = ast_true(tmp);
134  if (loguniqueid)
135  ast_debug(1, "logging CDR field UNIQUEID\n");
136  }
137 
138  if ((tmp = ast_variable_retrieve(cfg, "csv", "loguserfield"))) {
139  loguserfield = ast_true(tmp);
140  if (loguserfield)
141  ast_debug(1, "logging CDR user-defined field\n");
142  }
143 
144  ast_config_destroy(cfg);
145  return 1;
146 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
static const char config[]
Definition: cdr_csv.c:57
static int loguniqueid
Definition: cdr_csv.c:54
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define var
Definition: ast_expr2f.c:606
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int accountlogs
Definition: cdr_csv.c:53
#define ast_config_load(filename, flags)
Load a config file.
Definition: config.h:170
static int reload(void)
Definition: cdr_csv.c:351
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int usegmtime
Definition: cdr_csv.c:52
static int loguserfield
Definition: cdr_csv.c:55
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int load_module ( void  )
static

Definition at line 336 of file cdr_csv.c.

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

337 {
338  int res;
339 
340  if(!load_config(0))
342 
344  ast_log(LOG_ERROR, "Unable to register CSV CDR handling\n");
345  } else {
346  loaded = 1;
347  }
348  return res;
349 }
const char * description
Definition: module.h:234
static int load_config(int reload)
Definition: cdr_csv.c:95
static int loaded
Definition: cdr_csv.c:56
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:130
#define LOG_ERROR
Definition: logger.h:155
static int csv_log(struct ast_cdr *cdr)
Definition: cdr_csv.c:291
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
static int reload ( void  )
static

Definition at line 351 of file cdr_csv.c.

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

352 {
353  if (load_config(1)) {
354  loaded = 1;
355  } else {
356  loaded = 0;
357  ast_log(LOG_WARNING, "No [csv] section in cdr.conf. Unregistering backend.\n");
359  }
360 
361  return 0;
362 }
#define LOG_WARNING
Definition: logger.h:144
static int load_config(int reload)
Definition: cdr_csv.c:95
static int loaded
Definition: cdr_csv.c:56
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static const char name[]
void ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:165
static int unload_module ( void  )
static

Definition at line 329 of file cdr_csv.c.

References ast_cdr_unregister().

330 {
332  loaded = 0;
333  return 0;
334 }
static int loaded
Definition: cdr_csv.c:56
static const char name[]
void ast_cdr_unregister(const char *name)
Unregister a CDR handling engine.
Definition: cdr.c:165
static int writefile ( char *  s,
char *  acc 
)
static

Definition at line 264 of file cdr_csv.c.

References acf_lock, ast_config_AST_LOG_DIR, ast_log(), ast_mutex_lock, ast_mutex_unlock, CSV_LOG_DIR, errno, f, LOG_ERROR, and LOG_WARNING.

Referenced by csv_log().

265 {
266  char tmp[PATH_MAX];
267  FILE *f;
268 
269  if (strchr(acc, '/') || (acc[0] == '.')) {
270  ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
271  return -1;
272  }
273 
274  snprintf(tmp, sizeof(tmp), "%s/%s/%s.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
275 
277  if (!(f = fopen(tmp, "a"))) {
279  ast_log(LOG_ERROR, "Unable to open file %s : %s\n", tmp, strerror(errno));
280  return -1;
281  }
282  fputs(s, f);
283  fflush(f);
284  fclose(f);
286 
287  return 0;
288 }
#define LOG_WARNING
Definition: logger.h:144
#define ast_mutex_lock(a)
Definition: lock.h:155
static ast_mutex_t acf_lock
Definition: cdr_csv.c:93
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
const char * ast_config_AST_LOG_DIR
Definition: asterisk.c:263
int errno
static struct ast_format f[]
Definition: format_g726.c:181
#define CSV_LOG_DIR
Definition: cdr_csv.c:47
#define ast_mutex_unlock(a)
Definition: lock.h:156

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Comma Separated Values CDR Backend" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CDR_DRIVER, }
static

Definition at line 369 of file cdr_csv.c.

int accountlogs
static

Definition at line 53 of file cdr_csv.c.

ast_mutex_t acf_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 93 of file cdr_csv.c.

Referenced by writefile().

Definition at line 369 of file cdr_csv.c.

int loaded = 0
static

Definition at line 56 of file cdr_csv.c.

int loguniqueid = 0
static

Definition at line 54 of file cdr_csv.c.

int loguserfield = 0
static

Definition at line 55 of file cdr_csv.c.

ast_mutex_t mf_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 92 of file cdr_csv.c.

Referenced by csv_log().

char* name = "csv"
static

Definition at line 90 of file cdr_csv.c.

int usegmtime = 0
static

Definition at line 52 of file cdr_csv.c.

Referenced by load_config().