Asterisk - The Open Source Telephony Project GIT-master-2de1a68
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 = "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 = 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 = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 
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 tmp()
Definition: bt_open.c:389
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, tmp(), 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, and tmp().

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,...)
Definition: utils/frame.c:999

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:3492
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:4372
char dstchannel[AST_MAX_EXTENSION]
Definition: cdr.h:291
long int disposition
Definition: cdr.h:307
char lastdata[AST_MAX_EXTENSION]
Definition: cdr.h:295
char linkedid[AST_MAX_UNIQUEID]
Definition: cdr.h:319
char userfield[AST_MAX_USER_FIELD]
Definition: cdr.h:321
long int billsec
Definition: cdr.h:305
struct timeval answer
Definition: cdr.h:299
char channel[AST_MAX_EXTENSION]
Definition: cdr.h:289
char peeraccount[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:313
long int duration
Definition: cdr.h:303
long int amaflags
Definition: cdr.h:309
char src[AST_MAX_EXTENSION]
Definition: cdr.h:283
char dst[AST_MAX_EXTENSION]
Definition: cdr.h:285
char clid[AST_MAX_EXTENSION]
Definition: cdr.h:281
char uniqueid[AST_MAX_UNIQUEID]
Definition: cdr.h:317
int sequence
Definition: cdr.h:323
struct timeval start
Definition: cdr.h:297
char accountcode[AST_MAX_ACCOUNT_CODE]
Definition: cdr.h:311
char lastapp[AST_MAX_EXTENSION]
Definition: cdr.h:293
char dcontext[AST_MAX_EXTENSION]
Definition: cdr.h:287
struct timeval end
Definition: cdr.h:301

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:190
#define ast_mutex_lock(a)
Definition: lock.h:189
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:1289
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
Definition: extconf.c:1215
@ CONFIG_FLAG_FILEUNCHANGED
const char * ast_config_AST_LOG_DIR
Definition: options.c:159
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:2199
Structure used to handle boolean flags.
Definition: utils.h:199
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.

Referenced by load_module(), and reload().

◆ 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}
int ast_cdr_register(const char *name, const char *desc, ast_cdrbe be)
Register a CDR handling engine.
Definition: cdr.c:3005
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
static int load_config(int reload)
Definition: cdr_csv.c:98
#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:352

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:3050

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 = "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 = 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

ast_mutex_t f_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

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(), and load_config().