Bug Summary

File:src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c
Location:line 247, column 5
Description:Value stored to 'fd' is never read

Annotated Source Code

1/*
2 * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3 * Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
4 *
5 * Version: MPL 1.1
6 *
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
15 * License.
16 *
17 * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18 *
19 * The Initial Developer of the Original Code is
20 * Anthony Minessale II <anthm@freeswitch.org>
21 * Portions created by the Initial Developer are Copyright (C)
22 * the Initial Developer. All Rights Reserved.
23 *
24 * Contributor(s):
25 *
26 * Brian West <brian@freeswitch.org>
27 * Bret McDanel <trixter AT 0xdecafbad.com>
28 * Justin Cassidy <xachenant@hotmail.com>
29 *
30 * mod_xml_cdr.c -- XML CDR Module to files or curl
31 *
32 */
33#include <switch.h>
34#include <sys/stat.h>
35#include <switch_curl.h>
36#define MAX_URLS20 20
37
38#define ENCODING_NONE0 0
39#define ENCODING_DEFAULT1 1
40#define ENCODING_BASE642 2
41#define ENCODING_TEXTXML3 3
42
43static struct {
44 char *cred;
45 char *urls[MAX_URLS20 + 1];
46 int url_count;
47 int url_index;
48 switch_thread_rwlock_t *log_path_lock;
49 char *base_log_dir;
50 char *base_err_log_dir;
51 char *log_dir;
52 char *err_log_dir;
53 uint32_t delay;
54 uint32_t retries;
55 uint32_t shutdown;
56 uint32_t enable_cacert_check;
57 char *ssl_cert_file;
58 char *ssl_key_file;
59 char *ssl_key_password;
60 char *ssl_version;
61 char *ssl_cacert_file;
62 uint32_t enable_ssl_verifyhost;
63 int encode;
64 int log_http_and_disk;
65 int log_b;
66 int prefix_a;
67 int disable100continue;
68 int rotate;
69 long auth_scheme;
70 int timeout;
71 switch_memory_pool_t *pool;
72 switch_event_node_t *node;
73} globals;
74
75SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)switch_status_t mod_xml_cdr_load (switch_loadable_module_interface_t
**module_interface, switch_memory_pool_t *pool)
;
76SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)switch_status_t mod_xml_cdr_shutdown (void);
77SWITCH_MODULE_DEFINITION(mod_xml_cdr, mod_xml_cdr_load, mod_xml_cdr_shutdown, NULL)static const char modname[] = "mod_xml_cdr" ; __attribute__((
visibility("default"))) switch_loadable_module_function_table_t
mod_xml_cdr_module_interface = { 5, mod_xml_cdr_load, mod_xml_cdr_shutdown
, ((void*)0), SMODF_NONE }
;
78
79/* this function would have access to the HTML returned by the webserver, we don't need it
80 * and the default curl activity is to print to stdout, something not as desirable
81 * so we have a dummy function here
82 */
83static size_t httpCallBack(char *buffer, size_t size, size_t nitems, void *outstream)
84{
85 return size * nitems;
86}
87
88static switch_status_t set_xml_cdr_log_dirs()
89{
90 switch_time_exp_t tm;
91 char *path = NULL((void*)0);
92 char date[80] = "";
93 switch_size_t retsize;
94 switch_status_t status = SWITCH_STATUS_SUCCESS, dir_status;
95
96 switch_time_exp_lt(&tm, switch_micro_time_now());
97 switch_strftime_nocheck(date, &retsize, sizeof(date), "%Y-%m-%d-%H-%M-%S", &tm);
98
99 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 99, ((void*)0)
, SWITCH_LOG_NOTICE, "Rotating log file paths\n");
100
101 if (!zstr(globals.base_log_dir)_zstr(globals.base_log_dir)) {
102 if (globals.rotate) {
103 if ((path = switch_mprintf("%s%s%s", globals.base_log_dir, SWITCH_PATH_SEPARATOR"/", date))) {
104 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 104, ((void*)0)
, SWITCH_LOG_NOTICE, "Rotating log file path to %s\n", path);
105
106 dir_status = SWITCH_STATUS_SUCCESS;
107 if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
108 dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT0x0FFF, globals.pool);
109 }
110
111 if (dir_status == SWITCH_STATUS_SUCCESS) {
112 switch_thread_rwlock_wrlock(globals.log_path_lock);
113 switch_safe_free(globals.log_dir)if (globals.log_dir) {free(globals.log_dir);globals.log_dir=(
(void*)0);}
;
114 globals.log_dir = path;
115 switch_thread_rwlock_unlock(globals.log_path_lock);
116 } else {
117 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 117, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to create new mod_xml_cdr log_dir path\n");
118 switch_safe_free(path)if (path) {free(path);path=((void*)0);};
119 status = SWITCH_STATUS_FALSE;
120 }
121 } else {
122 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 122, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to generate new mod_xml_cdr log_dir path\n");
123 status = SWITCH_STATUS_FALSE;
124 }
125 } else {
126 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 126, ((void*)0)
, SWITCH_LOG_NOTICE, "Setting log file path to %s\n", globals.base_log_dir);
127 if ((path = switch_safe_strdup(globals.base_log_dir))) {
128 switch_thread_rwlock_wrlock(globals.log_path_lock);
129 switch_safe_free(globals.log_dir)if (globals.log_dir) {free(globals.log_dir);globals.log_dir=(
(void*)0);}
;
130 switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, globals.pool);
131 globals.log_dir = path;
132 switch_thread_rwlock_unlock(globals.log_path_lock);
133 } else {
134 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 134, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to set log_dir path\n");
135 status = SWITCH_STATUS_FALSE;
136 }
137 }
138 }
139
140 if (!zstr(globals.base_err_log_dir)_zstr(globals.base_err_log_dir)) {
141 if (globals.rotate) {
142 if ((path = switch_mprintf("%s%s%s", globals.base_err_log_dir, SWITCH_PATH_SEPARATOR"/", date))) {
143 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 143, ((void*)0)
, SWITCH_LOG_NOTICE, "Rotating err log file path to %s\n", path);
144
145 dir_status = SWITCH_STATUS_SUCCESS;
146 if (switch_directory_exists(path, globals.pool) != SWITCH_STATUS_SUCCESS) {
147 dir_status = switch_dir_make(path, SWITCH_FPROT_OS_DEFAULT0x0FFF, globals.pool);
148 }
149
150 if (dir_status == SWITCH_STATUS_SUCCESS) {
151 switch_thread_rwlock_wrlock(globals.log_path_lock);
152 switch_safe_free(globals.err_log_dir)if (globals.err_log_dir) {free(globals.err_log_dir);globals.err_log_dir
=((void*)0);}
;
153 globals.err_log_dir = path;
154 switch_thread_rwlock_unlock(globals.log_path_lock);
155 } else {
156 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 156, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to create new mod_xml_cdr err_log_dir path\n");
157 switch_safe_free(path)if (path) {free(path);path=((void*)0);};
158 status = SWITCH_STATUS_FALSE;
159 }
160 } else {
161 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 161, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to generate new mod_xml_cdr err_log_dir path\n");
162 status = SWITCH_STATUS_FALSE;
163 }
164 } else {
165 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 165, ((void*)0)
, SWITCH_LOG_NOTICE, "Setting err log file path to %s\n", globals.base_err_log_dir);
166 if ((path = switch_safe_strdup(globals.base_err_log_dir))) {
167 switch_thread_rwlock_wrlock(globals.log_path_lock);
168 switch_safe_free(globals.err_log_dir)if (globals.err_log_dir) {free(globals.err_log_dir);globals.err_log_dir
=((void*)0);}
;
169 switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS0x0400 | 0x0200 | 0x0100 | 0x0040 | 0x0010, globals.pool);
170 globals.err_log_dir = path;
171 switch_thread_rwlock_unlock(globals.log_path_lock);
172 } else {
173 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 173, ((void*)0)
, SWITCH_LOG_ERROR, "Failed to set err_log_dir path\n");
174 status = SWITCH_STATUS_FALSE;
175 }
176 }
177 }
178
179 return status;
180}
181
182static switch_status_t my_on_reporting(switch_core_session_t *session)
183{
184 switch_xml_t cdr = NULL((void*)0);
185 char *xml_text = NULL((void*)0);
186 char *path = NULL((void*)0);
187 char *curl_xml_text = NULL((void*)0);
188 const char *logdir = NULL((void*)0);
189 char *xml_text_escaped = NULL((void*)0);
190 int fd = -1;
191 uint32_t cur_try;
192 long httpRes;
193 switch_CURL *curl_handle = NULL((void*)0);
194 switch_curl_slist_t *headers = NULL((void*)0);
195 switch_curl_slist_t *slist = NULL((void*)0);
196 switch_channel_t *channel = switch_core_session_get_channel(session);
197 switch_status_t status = SWITCH_STATUS_FALSE;
198 int is_b;
199 const char *a_prefix = "";
200 char url_joiner = '?';
201
202 if (globals.shutdown) {
203 return SWITCH_STATUS_SUCCESS;
204 }
205
206 is_b = channel && switch_channel_get_originator_caller_profile(channel);
207 if (!globals.log_b && is_b) {
208 const char *force_cdr = switch_channel_get_variable(channel, SWITCH_FORCE_PROCESS_CDR_VARIABLE)switch_channel_get_variable_dup(channel, "force_process_cdr",
SWITCH_TRUE, -1)
;
209 if (!switch_true(force_cdr)) {
210 return SWITCH_STATUS_SUCCESS;
211 }
212 }
213 if (!is_b && globals.prefix_a)
214 a_prefix = "a_";
215
216 if (switch_ivr_generate_xml_cdr(session, &cdr) != SWITCH_STATUS_SUCCESS) {
217 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 217, ((void*)0)
, SWITCH_LOG_ERROR, "Error Generating Data!\n");
218 return SWITCH_STATUS_FALSE;
219 }
220
221 /* build the XML */
222 xml_text = switch_xml_toxml(cdr, SWITCH_TRUE);
223 if (!xml_text) {
224 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 224, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
225 goto error;
226 }
227
228 switch_thread_rwlock_rdlock(globals.log_path_lock);
229
230 if (!(logdir = switch_channel_get_variable(channel, "xml_cdr_base")switch_channel_get_variable_dup(channel, "xml_cdr_base", SWITCH_TRUE
, -1)
)) {
231 logdir = globals.log_dir;
232 }
233
234 if (!zstr(logdir)_zstr(logdir) && (globals.log_http_and_disk || !globals.url_count)) {
235 path = switch_mprintf("%s%s%s%s.cdr.xml", logdir, SWITCH_PATH_SEPARATOR"/", a_prefix, switch_core_session_get_uuid(session));
236 switch_thread_rwlock_unlock(globals.log_path_lock);
237 if (path) {
238#ifdef _MSC_VER
239 if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200)) > -1) {
240#else
241 if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200 | S_IRGRP(0400 >> 3) | S_IWGRP(0200 >> 3) | S_IROTH((0400 >> 3) >> 3) | S_IWOTH((0200 >> 3) >> 3))) > -1) {
242#endif
243 int wrote;
244 wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
245 wrote++;
246 close(fd);
247 fd = -1;
Value stored to 'fd' is never read
248 } else {
249 char ebuf[512] = { 0 };
250 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 250, ((void*)0)
, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n",
251 path, switch_strerror_r(errno(*__errno_location ()), ebuf, sizeof(ebuf)));
252 }
253 switch_safe_free(path)if (path) {free(path);path=((void*)0);};
254 }
255 } else {
256 switch_thread_rwlock_unlock(globals.log_path_lock);
257 }
258
259 /* try to post it to the web server */
260 if (globals.url_count) {
261 char *destUrl = NULL((void*)0);
262 curl_handle = switch_curl_easy_init();
263
264 if (globals.encode == ENCODING_TEXTXML3) {
265 headers = switch_curl_slist_append(headers, "Content-Type: text/xml");
266 } else if (globals.encode) {
267 switch_size_t need_bytes = strlen(xml_text) * 3 + 1;
268
269 xml_text_escaped = malloc(need_bytes);
270 switch_assert(xml_text_escaped)((xml_text_escaped) ? (void) (0) : __assert_fail ("xml_text_escaped"
, "mod_xml_cdr.c", 270, __PRETTY_FUNCTION__))
;
271 memset(xml_text_escaped, 0, need_bytes);
272 if (globals.encode == ENCODING_DEFAULT1) {
273 headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
274 switch_url_encode(xml_text, xml_text_escaped, need_bytes);
275 } else {
276 headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-base64-encoded");
277 switch_b64_encode((unsigned char *) xml_text, need_bytes / 3, (unsigned char *) xml_text_escaped, need_bytes);
278 }
279 switch_safe_free(xml_text)if (xml_text) {free(xml_text);xml_text=((void*)0);};
280 xml_text = xml_text_escaped;
281 } else {
282 headers = switch_curl_slist_append(headers, "Content-Type: application/x-www-form-plaintext");
283 }
284
285 if (globals.encode == ENCODING_TEXTXML3) {
286 curl_xml_text = xml_text;
287 } else if (!(curl_xml_text = switch_mprintf("cdr=%s", xml_text))) {
288 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 288, ((void*)0)
, SWITCH_LOG_CRIT, "Memory Error!\n");
289 goto error;
290 }
291
292 if (!zstr(globals.cred)_zstr(globals.cred)) {
293 switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPAUTH, globals.auth_scheme)curl_easy_setopt(curl_handle,CURLOPT_HTTPAUTH,globals.auth_scheme
)
;
294 switch_curl_easy_setopt(curl_handle, CURLOPT_USERPWD, globals.cred)curl_easy_setopt(curl_handle,CURLOPT_USERPWD,globals.cred);
295 }
296
297 switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers)curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER,headers);
298 switch_curl_easy_setopt(curl_handle, CURLOPT_POST, 1)curl_easy_setopt(curl_handle,CURLOPT_POST,1);
299 switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1)curl_easy_setopt(curl_handle,CURLOPT_NOSIGNAL,1);
300 switch_curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, curl_xml_text)curl_easy_setopt(curl_handle,CURLOPT_POSTFIELDS,curl_xml_text
)
;
301 switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-xml/1.0")curl_easy_setopt(curl_handle,CURLOPT_USERAGENT,"freeswitch-xml/1.0"
)
;
302 switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, httpCallBack)curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,httpCallBack
)
;
303
304 if (globals.disable100continue) {
305 slist = switch_curl_slist_append(slist, "Expect:");
306 switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, slist)curl_easy_setopt(curl_handle,CURLOPT_HTTPHEADER,slist);
307 }
308
309 if (globals.ssl_cert_file) {
310 switch_curl_easy_setopt(curl_handle, CURLOPT_SSLCERT, globals.ssl_cert_file)curl_easy_setopt(curl_handle,CURLOPT_SSLCERT,globals.ssl_cert_file
)
;
311 }
312
313 if (globals.ssl_key_file) {
314 switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEY, globals.ssl_key_file)curl_easy_setopt(curl_handle,CURLOPT_SSLKEY,globals.ssl_key_file
)
;
315 }
316
317 if (globals.ssl_key_password) {
318 switch_curl_easy_setopt(curl_handle, CURLOPT_SSLKEYPASSWD, globals.ssl_key_password)curl_easy_setopt(curl_handle,CURLOPT_KEYPASSWD,globals.ssl_key_password
)
;
319 }
320
321 if (globals.ssl_version) {
322 if (!strcasecmp(globals.ssl_version, "SSLv3")) {
323 switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_SSLv3)curl_easy_setopt(curl_handle,CURLOPT_SSLVERSION,CURL_SSLVERSION_SSLv3
)
;
324 } else if (!strcasecmp(globals.ssl_version, "TLSv1")) {
325 switch_curl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1)curl_easy_setopt(curl_handle,CURLOPT_SSLVERSION,CURL_SSLVERSION_TLSv1
)
;
326 }
327 }
328
329 if (globals.ssl_cacert_file) {
330 switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, globals.ssl_cacert_file)curl_easy_setopt(curl_handle,CURLOPT_CAINFO,globals.ssl_cacert_file
)
;
331 }
332
333 switch_curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, globals.timeout)curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT,globals.timeout);
334
335 /* these were used for testing, optionally they may be enabled if someone desires
336 switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1); // 302 recursion level
337 */
338
339 for (cur_try = 0; cur_try < globals.retries; cur_try++) {
340 if (cur_try > 0) {
341 switch_yield(globals.delay * 1000000)switch_sleep(globals.delay * 1000000);;
342 }
343
344 if( strchr(globals.urls[globals.url_index], '?')(__extension__ (__builtin_constant_p ('?') && !__builtin_constant_p
(globals.urls[globals.url_index]) && ('?') == '\0' ?
(char *) __rawmemchr (globals.urls[globals.url_index], '?') :
__builtin_strchr (globals.urls[globals.url_index], '?')))
!= NULL((void*)0) ) {
345 url_joiner = '&';
346 }
347 destUrl = switch_mprintf("%s%cuuid=%s%s", globals.urls[globals.url_index], url_joiner, a_prefix, switch_core_session_get_uuid(session));
348 switch_curl_easy_setopt(curl_handle, CURLOPT_URL, destUrl)curl_easy_setopt(curl_handle,CURLOPT_URL,destUrl);
349
350 if (!strncasecmp(destUrl, "https", 5)) {
351 switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0)curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,0);
352 switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0)curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,0);
353 }
354
355 if (globals.enable_cacert_check) {
356 switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, TRUE)curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYPEER,(!0));
357 }
358
359 if (globals.enable_ssl_verifyhost) {
360 switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 2)curl_easy_setopt(curl_handle,CURLOPT_SSL_VERIFYHOST,2);
361 }
362
363 switch_curl_easy_perform(curl_handle);
364 switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
365 switch_safe_free(destUrl)if (destUrl) {free(destUrl);destUrl=((void*)0);};
366 if (httpRes >= 200 && httpRes <= 299) {
367 goto success;
368 } else {
369 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 369, ((void*)0)
, SWITCH_LOG_ERROR, "Got error [%ld] posting to web server [%s]\n",
370 httpRes, globals.urls[globals.url_index]);
371 globals.url_index++;
372 switch_assert(globals.url_count <= MAX_URLS)((globals.url_count <= 20) ? (void) (0) : __assert_fail ("globals.url_count <= 20"
, "mod_xml_cdr.c", 372, __PRETTY_FUNCTION__))
;
373 if (globals.url_index >= globals.url_count) {
374 globals.url_index = 0;
375 }
376 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 376, ((void*)0)
, SWITCH_LOG_ERROR, "Retry will be with url [%s]\n", globals.urls[globals.url_index]);
377 }
378 }
379 switch_curl_easy_cleanup(curl_handle);
380 switch_curl_slist_free_all(headers);
381 switch_curl_slist_free_all(slist);
382 slist = NULL((void*)0);
383 headers = NULL((void*)0);
384 curl_handle = NULL((void*)0);
385
386 /* if we are here the web post failed for some reason */
387 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 387, ((void*)0)
, SWITCH_LOG_ERROR, "Unable to post to web server, writing to file\n");
388
389 switch_thread_rwlock_rdlock(globals.log_path_lock);
390 path = switch_mprintf("%s%s%s%s.cdr.xml", globals.err_log_dir, SWITCH_PATH_SEPARATOR"/", a_prefix, switch_core_session_get_uuid(session));
391 switch_thread_rwlock_unlock(globals.log_path_lock);
392 if (path) {
393#ifdef _MSC_VER
394 if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200)) > -1) {
395#else
396 if ((fd = open(path, O_WRONLY01 | O_CREAT0100 | O_TRUNC01000, S_IRUSR0400 | S_IWUSR0200 | S_IRGRP(0400 >> 3) | S_IWGRP(0200 >> 3) | S_IROTH((0400 >> 3) >> 3) | S_IWOTH((0200 >> 3) >> 3))) > -1) {
397#endif
398 int wrote;
399 wrote = write(fd, xml_text, (unsigned) strlen(xml_text));
400 wrote++;
401 close(fd);
402 fd = -1;
403 } else {
404 char ebuf[512] = { 0 };
405 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 405, ((void*)0)
, SWITCH_LOG_ERROR, "Error![%s]\n",
406 switch_strerror_r(errno(*__errno_location ()), ebuf, sizeof(ebuf)));
407 }
408 }
409 }
410
411 success:
412 status = SWITCH_STATUS_SUCCESS;
413
414 error:
415 if (curl_handle) {
416 switch_curl_easy_cleanup(curl_handle);
417 }
418 if (headers) {
419 switch_curl_slist_free_all(headers);
420 }
421 if (slist) {
422 switch_curl_slist_free_all(slist);
423 }
424 if (curl_xml_text != xml_text) {
425 switch_safe_free(curl_xml_text)if (curl_xml_text) {free(curl_xml_text);curl_xml_text=((void*
)0);}
;
426 }
427 switch_safe_free(xml_text)if (xml_text) {free(xml_text);xml_text=((void*)0);};
428 switch_safe_free(path)if (path) {free(path);path=((void*)0);};
429 switch_xml_free(cdr);
430
431 return status;
432}
433
434static void event_handler(switch_event_t *event)
435{
436 const char *sig = switch_event_get_header(event, "Trapped-Signal")switch_event_get_header_idx(event, "Trapped-Signal", -1);
437
438 if (sig && !strcmp(sig, "HUP")__extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p
(sig) && __builtin_constant_p ("HUP") && (__s1_len
= __builtin_strlen (sig), __s2_len = __builtin_strlen ("HUP"
), (!((size_t)(const void *)((sig) + 1) - (size_t)(const void
*)(sig) == 1) || __s1_len >= 4) && (!((size_t)(const
void *)(("HUP") + 1) - (size_t)(const void *)("HUP") == 1) ||
__s2_len >= 4)) ? __builtin_strcmp (sig, "HUP") : (__builtin_constant_p
(sig) && ((size_t)(const void *)((sig) + 1) - (size_t
)(const void *)(sig) == 1) && (__s1_len = __builtin_strlen
(sig), __s1_len < 4) ? (__builtin_constant_p ("HUP") &&
((size_t)(const void *)(("HUP") + 1) - (size_t)(const void *
)("HUP") == 1) ? __builtin_strcmp (sig, "HUP") : (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) ("HUP"); int __result = (((const unsigned char *) (const
char *) (sig))[0] - __s2[0]); if (__s1_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (sig))[1] - __s2[1]); if (__s1_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) (sig))[2] - __s2[2]); if (__s1_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) (sig))[3] - __s2[3]); } } __result; }))) : (__builtin_constant_p
("HUP") && ((size_t)(const void *)(("HUP") + 1) - (size_t
)(const void *)("HUP") == 1) && (__s2_len = __builtin_strlen
("HUP"), __s2_len < 4) ? (__builtin_constant_p (sig) &&
((size_t)(const void *)((sig) + 1) - (size_t)(const void *)(
sig) == 1) ? __builtin_strcmp (sig, "HUP") : (- (__extension__
({ const unsigned char *__s2 = (const unsigned char *) (const
char *) (sig); int __result = (((const unsigned char *) (const
char *) ("HUP"))[0] - __s2[0]); if (__s2_len > 0 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("HUP"))[1] - __s2[1]); if (__s2_len > 1 &&
__result == 0) { __result = (((const unsigned char *) (const
char *) ("HUP"))[2] - __s2[2]); if (__s2_len > 2 &&
__result == 0) __result = (((const unsigned char *) (const char
*) ("HUP"))[3] - __s2[3]); } } __result; })))) : __builtin_strcmp
(sig, "HUP")))); })
) {
439 if (globals.rotate) {
440 set_xml_cdr_log_dirs();
441 }
442 }
443}
444
445static switch_state_handler_table_t state_handlers = {
446 /*.on_init */ NULL((void*)0),
447 /*.on_routing */ NULL((void*)0),
448 /*.on_execute */ NULL((void*)0),
449 /*.on_hangup */ NULL((void*)0),
450 /*.on_exchange_media */ NULL((void*)0),
451 /*.on_soft_execute */ NULL((void*)0),
452 /*.on_consume_media */ NULL((void*)0),
453 /*.on_hibernate */ NULL((void*)0),
454 /*.on_reset */ NULL((void*)0),
455 /*.on_park */ NULL((void*)0),
456 /*.on_reporting */ my_on_reporting
457};
458
459SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)switch_status_t mod_xml_cdr_load (switch_loadable_module_interface_t
**module_interface, switch_memory_pool_t *pool)
460{
461 char *cf = "xml_cdr.conf";
462 switch_xml_t cfg, xml, settings, param;
463 switch_status_t status = SWITCH_STATUS_SUCCESS;
464
465 /* test global state handlers */
466 switch_core_add_state_handler(&state_handlers);
467
468 *module_interface = switch_loadable_module_create_module_interface(pool, modname);
469
470 memset(&globals, 0, sizeof(globals));
471
472 if (switch_event_bind_removable(modname, SWITCH_EVENT_TRAP, SWITCH_EVENT_SUBCLASS_ANY((void*)0), event_handler, NULL((void*)0), &globals.node) != SWITCH_STATUS_SUCCESS) {
473 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 473, ((void*)0)
, SWITCH_LOG_ERROR, "Couldn't bind!\n");
474 return SWITCH_STATUS_GENERR;
475 }
476
477 globals.log_http_and_disk = 0;
478 globals.log_b = 1;
479 globals.disable100continue = 0;
480 globals.pool = pool;
481 globals.auth_scheme = CURLAUTH_BASIC(((unsigned long)1)<<0);
482
483 switch_thread_rwlock_create(&globals.log_path_lock, pool);
484
485 /* parse the config */
486 if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL((void*)0)))) {
487 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 487, ((void*)0)
, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
488 return SWITCH_STATUS_FALSE;
489 }
490
491 if ((settings = switch_xml_child(cfg, "settings"))) {
492 for (param = switch_xml_child(settings, "param"); param; param = param->next) {
493 char *var = (char *) switch_xml_attr_soft(param, "name");
494 char *val = (char *) switch_xml_attr_soft(param, "value");
495
496 if (!strcasecmp(var, "cred") && !zstr(val)_zstr(val)) {
497 globals.cred = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 497)
;
498 } else if (!strcasecmp(var, "url") && !zstr(val)_zstr(val)) {
499 if (globals.url_count >= MAX_URLS20) {
500 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 500, ((void*)0)
, SWITCH_LOG_ERROR, "maximum urls configured!\n");
501 } else {
502 globals.urls[globals.url_count++] = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 502)
;
503 }
504 } else if (!strcasecmp(var, "log-http-and-disk")) {
505 globals.log_http_and_disk = switch_true(val);
506 } else if (!strcasecmp(var, "timeout")) {
507 int tmp = atoi(val);
508 if (tmp >= 0) {
509 globals.timeout = tmp;
510 } else {
511 globals.timeout = 0;
512 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 512, ((void*)0)
, SWITCH_LOG_ERROR, "Can't set a negative timeout!\n");
513 }
514 } else if (!strcasecmp(var, "delay") && !zstr(val)_zstr(val)) {
515 globals.delay = switch_atoui(val);
516 } else if (!strcasecmp(var, "log-b-leg")) {
517 globals.log_b = switch_true(val);
518 } else if (!strcasecmp(var, "prefix-a-leg")) {
519 globals.prefix_a = switch_true(val);
520 } else if (!strcasecmp(var, "disable-100-continue") && switch_true(val)) {
521 globals.disable100continue = 1;
522 } else if (!strcasecmp(var, "encode") && !zstr(val)_zstr(val)) {
523 if (!strcasecmp(val, "base64")) {
524 globals.encode = ENCODING_BASE642;
525 } else if (!strcasecmp(val, "textxml")) {
526 globals.encode = ENCODING_TEXTXML3;
527 } else {
528 globals.encode = switch_true(val) ? ENCODING_DEFAULT1 : ENCODING_NONE0;
529 }
530 } else if (!strcasecmp(var, "retries") && !zstr(val)_zstr(val)) {
531 globals.retries = switch_atoui(val);
532 } else if (!strcasecmp(var, "rotate") && !zstr(val)_zstr(val)) {
533 globals.rotate = switch_true(val);
534 } else if (!strcasecmp(var, "log-dir")) {
535 if (zstr(val)_zstr(val)) {
536 globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%sxml_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/");
537 } else {
538 if (switch_is_file_path(val)) {
539 globals.base_log_dir = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 539)
;
540 } else {
541 globals.base_log_dir = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/", val);
542 }
543 }
544 } else if (!strcasecmp(var, "err-log-dir")) {
545 if (zstr(val)_zstr(val)) {
546 globals.base_err_log_dir = switch_core_sprintf(globals.pool, "%s%sxml_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/");
547 } else {
548 if (switch_is_file_path(val)) {
549 globals.base_err_log_dir = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 549)
;
550 } else {
551 globals.base_err_log_dir = switch_core_sprintf(globals.pool, "%s%s%s", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/", val);
552 }
553 }
554 } else if (!strcasecmp(var, "enable-cacert-check") && switch_true(val)) {
555 globals.enable_cacert_check = 1;
556 } else if (!strcasecmp(var, "ssl-cert-path")) {
557 globals.ssl_cert_file = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 557)
;
558 } else if (!strcasecmp(var, "ssl-key-path")) {
559 globals.ssl_key_file = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 559)
;
560 } else if (!strcasecmp(var, "ssl-key-password")) {
561 globals.ssl_key_password = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 561)
;
562 } else if (!strcasecmp(var, "ssl-version")) {
563 globals.ssl_version = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 563)
;
564 } else if (!strcasecmp(var, "ssl-cacert-file")) {
565 globals.ssl_cacert_file = switch_core_strdup(globals.pool, val)switch_core_perform_strdup(globals.pool, val, "mod_xml_cdr.c"
, (const char *)__func__, 565)
;
566 } else if (!strcasecmp(var, "enable-ssl-verifyhost") && switch_true(val)) {
567 globals.enable_ssl_verifyhost = 1;
568 } else if (!strcasecmp(var, "auth-scheme")) {
569 if (*val == '=') {
570 globals.auth_scheme = 0;
571 val++;
572 }
573
574 if (!strcasecmp(val, "basic")) {
575 globals.auth_scheme |= CURLAUTH_BASIC(((unsigned long)1)<<0);
576 } else if (!strcasecmp(val, "digest")) {
577 globals.auth_scheme |= CURLAUTH_DIGEST(((unsigned long)1)<<1);
578 } else if (!strcasecmp(val, "NTLM")) {
579 globals.auth_scheme |= CURLAUTH_NTLM(((unsigned long)1)<<3);
580 } else if (!strcasecmp(val, "GSS-NEGOTIATE")) {
581 globals.auth_scheme |= CURLAUTH_GSSNEGOTIATE(((unsigned long)1)<<2);
582 } else if (!strcasecmp(val, "any")) {
583 globals.auth_scheme = (long)CURLAUTH_ANY(~(((unsigned long)1)<<4));
584 }
585 }
586 }
587
588 if (zstr(globals.base_err_log_dir)_zstr(globals.base_err_log_dir)) {
589 if (!zstr(globals.base_log_dir)_zstr(globals.base_log_dir)) {
590 globals.base_err_log_dir = switch_core_strdup(globals.pool, globals.base_log_dir)switch_core_perform_strdup(globals.pool, globals.base_log_dir
, "mod_xml_cdr.c", (const char *)__func__, 590)
;
591 } else {
592 globals.base_err_log_dir = switch_core_sprintf(globals.pool, "%s%sxml_cdr", SWITCH_GLOBAL_dirs.log_dir, SWITCH_PATH_SEPARATOR"/");
593 }
594 }
595
596 }
597
598 if (globals.retries && globals.delay == 0) {
599 switch_log_printf(SWITCH_CHANNEL_LOGSWITCH_CHANNEL_ID_LOG, "mod_xml_cdr.c", (const char *)__func__
, 599, ((void*)0)
, SWITCH_LOG_ERROR, "Retries set but delay 0 setting to 5 seconds\n");
600 globals.delay = 5;
601 }
602
603 globals.retries++;
604
605 set_xml_cdr_log_dirs();
606
607 switch_xml_free(xml);
608
609 return status;
610}
611
612SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)switch_status_t mod_xml_cdr_shutdown (void)
613{
614
615 globals.shutdown = 1;
616
617 switch_safe_free(globals.log_dir)if (globals.log_dir) {free(globals.log_dir);globals.log_dir=(
(void*)0);}
;
618 switch_safe_free(globals.err_log_dir)if (globals.err_log_dir) {free(globals.err_log_dir);globals.err_log_dir
=((void*)0);}
;
619
620 switch_event_unbind(&globals.node);
621 switch_core_remove_state_handler(&state_handlers);
622
623 switch_thread_rwlock_destroy(globals.log_path_lock);
624
625 return SWITCH_STATUS_SUCCESS;
626}
627
628/* For Emacs:
629 * Local Variables:
630 * mode:c
631 * indent-tabs-mode:t
632 * tab-width:4
633 * c-basic-offset:4
634 * End:
635 * For VIM:
636 * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
637 */