File: | src/mod/xml_int/mod_xml_cdr/mod_xml_cdr.c |
Location: | line 402, column 5 |
Description: | Value stored to 'fd' is never read |
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 | |
43 | static 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 | |
75 | SWITCH_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); |
76 | SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)switch_status_t mod_xml_cdr_shutdown (void); |
77 | SWITCH_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 | */ |
83 | static size_t httpCallBack(char *buffer, size_t size, size_t nitems, void *outstream) |
84 | { |
85 | return size * nitems; |
86 | } |
87 | |
88 | static 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 | |
182 | static 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; |
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; |
Value stored to 'fd' is never read | |
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 | |
434 | static 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 | |
445 | static 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 | |
459 | SWITCH_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 | |
612 | SWITCH_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 | */ |