1 | /* logging.c
|
---|
2 | *
|
---|
3 | * Copyright (C) 2006-2017 wolfSSL Inc.
|
---|
4 | *
|
---|
5 | * This file is part of wolfSSL.
|
---|
6 | *
|
---|
7 | * wolfSSL is free software; you can redistribute it and/or modify
|
---|
8 | * it under the terms of the GNU General Public License as published by
|
---|
9 | * the Free Software Foundation; either version 2 of the License, or
|
---|
10 | * (at your option) any later version.
|
---|
11 | *
|
---|
12 | * wolfSSL is distributed in the hope that it will be useful,
|
---|
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
15 | * GNU General Public License for more details.
|
---|
16 | *
|
---|
17 | * You should have received a copy of the GNU General Public License
|
---|
18 | * along with this program; if not, write to the Free Software
|
---|
19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
---|
20 | */
|
---|
21 |
|
---|
22 |
|
---|
23 | #ifdef HAVE_CONFIG_H
|
---|
24 | #include <config.h>
|
---|
25 | #endif
|
---|
26 |
|
---|
27 | #include <wolfssl/wolfcrypt/settings.h>
|
---|
28 |
|
---|
29 | /* submitted by eof */
|
---|
30 |
|
---|
31 | #include <wolfssl/wolfcrypt/logging.h>
|
---|
32 | #include <wolfssl/wolfcrypt/error-crypt.h>
|
---|
33 |
|
---|
34 |
|
---|
35 | #ifdef __cplusplus
|
---|
36 | extern "C" {
|
---|
37 | #endif
|
---|
38 | WOLFSSL_API int wolfSSL_Debugging_ON(void);
|
---|
39 | WOLFSSL_API void wolfSSL_Debugging_OFF(void);
|
---|
40 | #ifdef __cplusplus
|
---|
41 | }
|
---|
42 | #endif
|
---|
43 |
|
---|
44 | #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
|
---|
45 | static wolfSSL_Mutex debug_mutex; /* mutex for access to debug structure */
|
---|
46 |
|
---|
47 | /* accessing any node from the queue should be wrapped in a lock of
|
---|
48 | * debug_mutex */
|
---|
49 | static void* wc_error_heap;
|
---|
50 | struct wc_error_queue {
|
---|
51 | void* heap; /* the heap hint used with nodes creation */
|
---|
52 | struct wc_error_queue* next;
|
---|
53 | struct wc_error_queue* prev;
|
---|
54 | char error[WOLFSSL_MAX_ERROR_SZ];
|
---|
55 | char file[WOLFSSL_MAX_ERROR_SZ];
|
---|
56 | int value;
|
---|
57 | int line;
|
---|
58 | };
|
---|
59 | volatile struct wc_error_queue* wc_errors;
|
---|
60 | static struct wc_error_queue* wc_last_node;
|
---|
61 | /* pointer to last node in queue to make insertion O(1) */
|
---|
62 | #endif
|
---|
63 |
|
---|
64 |
|
---|
65 |
|
---|
66 | #if defined(DEBUG_WOLFSSL)
|
---|
67 |
|
---|
68 | /* Set these to default values initially. */
|
---|
69 | static wolfSSL_Logging_cb log_function = NULL;
|
---|
70 | static int loggingEnabled = 0;
|
---|
71 |
|
---|
72 | #endif /* DEBUG_WOLFSSL */
|
---|
73 |
|
---|
74 |
|
---|
75 | int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f)
|
---|
76 | {
|
---|
77 | #ifdef DEBUG_WOLFSSL
|
---|
78 | int res = 0;
|
---|
79 |
|
---|
80 | if (f)
|
---|
81 | log_function = f;
|
---|
82 | else
|
---|
83 | res = BAD_FUNC_ARG;
|
---|
84 |
|
---|
85 | return res;
|
---|
86 | #else
|
---|
87 | (void)f;
|
---|
88 | return NOT_COMPILED_IN;
|
---|
89 | #endif
|
---|
90 | }
|
---|
91 |
|
---|
92 |
|
---|
93 | int wolfSSL_Debugging_ON(void)
|
---|
94 | {
|
---|
95 | #ifdef DEBUG_WOLFSSL
|
---|
96 | loggingEnabled = 1;
|
---|
97 | return 0;
|
---|
98 | #else
|
---|
99 | return NOT_COMPILED_IN;
|
---|
100 | #endif
|
---|
101 | }
|
---|
102 |
|
---|
103 |
|
---|
104 | void wolfSSL_Debugging_OFF(void)
|
---|
105 | {
|
---|
106 | #ifdef DEBUG_WOLFSSL
|
---|
107 | loggingEnabled = 0;
|
---|
108 | #endif
|
---|
109 | }
|
---|
110 |
|
---|
111 |
|
---|
112 | #ifdef DEBUG_WOLFSSL
|
---|
113 |
|
---|
114 | #if defined(FREESCALE_MQX) || defined(FREESCALE_KSDK_MQX)
|
---|
115 | #if MQX_USE_IO_OLD
|
---|
116 | #include <fio.h>
|
---|
117 | #else
|
---|
118 | #include <nio.h>
|
---|
119 | #endif
|
---|
120 | #elif defined(WOLFSSL_SGX)
|
---|
121 | /* Declare sprintf for ocall */
|
---|
122 | int sprintf(char* buf, const char *fmt, ...);
|
---|
123 | #elif defined(MICRIUM)
|
---|
124 | #include <bsp_ser.h>
|
---|
125 | #else
|
---|
126 | #include <stdio.h> /* for default printf stuff */
|
---|
127 | #endif
|
---|
128 |
|
---|
129 | #if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
|
---|
130 | int dc_log_printf(char*, ...);
|
---|
131 | #endif
|
---|
132 |
|
---|
133 | static void wolfssl_log(const int logLevel, const char *const logMessage)
|
---|
134 | {
|
---|
135 | if (log_function)
|
---|
136 | log_function(logLevel, logMessage);
|
---|
137 | else {
|
---|
138 | if (loggingEnabled) {
|
---|
139 | #if defined(THREADX) && !defined(THREADX_NO_DC_PRINTF)
|
---|
140 | dc_log_printf("%s\n", logMessage);
|
---|
141 | #elif defined(MICRIUM)
|
---|
142 | BSP_Ser_Printf("%s\r\n", logMessage);
|
---|
143 | #elif defined(WOLFSSL_MDK_ARM)
|
---|
144 | fflush(stdout) ;
|
---|
145 | printf("%s\n", logMessage);
|
---|
146 | fflush(stdout) ;
|
---|
147 | #elif defined(WOLFSSL_LOG_PRINTF)
|
---|
148 | printf("%s\n", logMessage);
|
---|
149 | #elif defined(WOLFSSL_UTASKER)
|
---|
150 | fnDebugMsg((char*)logMessage);
|
---|
151 | fnDebugMsg("\r\n");
|
---|
152 | #elif defined(MQX_USE_IO_OLD)
|
---|
153 | fprintf(_mqxio_stderr, "%s\n", logMessage);
|
---|
154 | #else
|
---|
155 | fprintf(stderr, "%s\n", logMessage);
|
---|
156 | #endif
|
---|
157 | }
|
---|
158 | }
|
---|
159 | }
|
---|
160 |
|
---|
161 |
|
---|
162 | void WOLFSSL_MSG(const char* msg)
|
---|
163 | {
|
---|
164 | if (loggingEnabled)
|
---|
165 | wolfssl_log(INFO_LOG , msg);
|
---|
166 | }
|
---|
167 |
|
---|
168 |
|
---|
169 | void WOLFSSL_BUFFER(const byte* buffer, word32 length)
|
---|
170 | {
|
---|
171 | #define LINE_LEN 16
|
---|
172 |
|
---|
173 | if (loggingEnabled) {
|
---|
174 | word32 i;
|
---|
175 | char line[80];
|
---|
176 |
|
---|
177 | if (!buffer) {
|
---|
178 | wolfssl_log(INFO_LOG, "\tNULL");
|
---|
179 |
|
---|
180 | return;
|
---|
181 | }
|
---|
182 |
|
---|
183 | sprintf(line, "\t");
|
---|
184 |
|
---|
185 | for (i = 0; i < LINE_LEN; i++) {
|
---|
186 | if (i < length)
|
---|
187 | sprintf(line + 1 + i * 3,"%02x ", buffer[i]);
|
---|
188 | else
|
---|
189 | sprintf(line + 1 + i * 3, " ");
|
---|
190 | }
|
---|
191 |
|
---|
192 | sprintf(line + 1 + LINE_LEN * 3, "| ");
|
---|
193 |
|
---|
194 | for (i = 0; i < LINE_LEN; i++)
|
---|
195 | if (i < length)
|
---|
196 | sprintf(line + 3 + LINE_LEN * 3 + i,
|
---|
197 | "%c", 31 < buffer[i] && buffer[i] < 127 ? buffer[i] : '.');
|
---|
198 |
|
---|
199 | wolfssl_log(INFO_LOG, line);
|
---|
200 |
|
---|
201 | if (length > LINE_LEN)
|
---|
202 | WOLFSSL_BUFFER(buffer + LINE_LEN, length - LINE_LEN);
|
---|
203 | }
|
---|
204 | }
|
---|
205 |
|
---|
206 |
|
---|
207 | void WOLFSSL_ENTER(const char* msg)
|
---|
208 | {
|
---|
209 | if (loggingEnabled) {
|
---|
210 | char buffer[80];
|
---|
211 | sprintf(buffer, "wolfSSL Entering %s", msg);
|
---|
212 | wolfssl_log(ENTER_LOG , buffer);
|
---|
213 | }
|
---|
214 | }
|
---|
215 |
|
---|
216 |
|
---|
217 | void WOLFSSL_LEAVE(const char* msg, int ret)
|
---|
218 | {
|
---|
219 | if (loggingEnabled) {
|
---|
220 | char buffer[80];
|
---|
221 | sprintf(buffer, "wolfSSL Leaving %s, return %d", msg, ret);
|
---|
222 | wolfssl_log(LEAVE_LOG , buffer);
|
---|
223 | }
|
---|
224 | }
|
---|
225 | #endif /* DEBUG_WOLFSSL */
|
---|
226 |
|
---|
227 | /*
|
---|
228 | * When using OPENSSL_EXTRA or DEBUG_WOLFSSL_VERBOSE macro then WOLFSSL_ERROR is
|
---|
229 | * mapped to new funtion WOLFSSL_ERROR_LINE which gets the line # and function
|
---|
230 | * name where WOLFSSL_ERROR is called at.
|
---|
231 | */
|
---|
232 | #if (defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX)) || defined(WOLFSSL_HAPROXY)
|
---|
233 | #if (defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE))
|
---|
234 | void WOLFSSL_ERROR_LINE(int error, const char* func, unsigned int line,
|
---|
235 | const char* file, void* usrCtx)
|
---|
236 | #else
|
---|
237 | void WOLFSSL_ERROR(int error)
|
---|
238 | #endif
|
---|
239 | {
|
---|
240 | #if defined(DEBUG_WOLFSSL) && !defined(WOLFSSL_NGINX)
|
---|
241 | if (loggingEnabled && error != WC_PENDING_E)
|
---|
242 | #endif
|
---|
243 | {
|
---|
244 | char buffer[80];
|
---|
245 | #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
|
---|
246 | (void)usrCtx; /* a user ctx for future flexibility */
|
---|
247 | (void)func;
|
---|
248 |
|
---|
249 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
250 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
251 | sprintf(buffer, "wolfSSL error occurred, error = %d", error);
|
---|
252 | }
|
---|
253 | else {
|
---|
254 | if (error < 0) error = error - (2*error); /*get absolute value*/
|
---|
255 | sprintf(buffer, "wolfSSL error occurred, error = %d line:%d file:%s",
|
---|
256 | error, line, file);
|
---|
257 | if (wc_AddErrorNode(error, line, buffer, (char*)file) != 0) {
|
---|
258 | WOLFSSL_MSG("Error creating logging node");
|
---|
259 | /* with void function there is no return here, continue on
|
---|
260 | * to unlock mutex and log what buffer was created. */
|
---|
261 | }
|
---|
262 |
|
---|
263 | wc_UnLockMutex(&debug_mutex);
|
---|
264 | }
|
---|
265 | #else
|
---|
266 | sprintf(buffer, "wolfSSL error occurred, error = %d", error);
|
---|
267 | #endif
|
---|
268 | #ifdef DEBUG_WOLFSSL
|
---|
269 | wolfssl_log(ERROR_LOG , buffer);
|
---|
270 | #endif
|
---|
271 | }
|
---|
272 | }
|
---|
273 |
|
---|
274 | #endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */
|
---|
275 |
|
---|
276 | #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE)
|
---|
277 | /* Internal function that is called by wolfCrypt_Init() */
|
---|
278 | int wc_LoggingInit(void)
|
---|
279 | {
|
---|
280 | if (wc_InitMutex(&debug_mutex) != 0) {
|
---|
281 | WOLFSSL_MSG("Bad Init Mutex");
|
---|
282 | return BAD_MUTEX_E;
|
---|
283 | }
|
---|
284 | wc_errors = NULL;
|
---|
285 | wc_last_node = NULL;
|
---|
286 |
|
---|
287 | return 0;
|
---|
288 | }
|
---|
289 |
|
---|
290 |
|
---|
291 | /* internal function that is called by wolfCrypt_Cleanup */
|
---|
292 | int wc_LoggingCleanup(void)
|
---|
293 | {
|
---|
294 | /* clear logging entries */
|
---|
295 | wc_ClearErrorNodes();
|
---|
296 |
|
---|
297 | /* free mutex */
|
---|
298 | if (wc_FreeMutex(&debug_mutex) != 0) {
|
---|
299 | WOLFSSL_MSG("Bad Mutex free");
|
---|
300 | return BAD_MUTEX_E;
|
---|
301 | }
|
---|
302 | return 0;
|
---|
303 | }
|
---|
304 |
|
---|
305 |
|
---|
306 | #if defined(DEBUG_WOLFSSL) || defined(WOLFSSL_NGINX) || \
|
---|
307 | defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE)
|
---|
308 | /* peek at an error node
|
---|
309 | *
|
---|
310 | * idx : if -1 then the most recent node is looked at, otherwise search
|
---|
311 | * through queue for node at the given index
|
---|
312 | * file : pointer to internal file string
|
---|
313 | * reason : pointer to internal error reason
|
---|
314 | * line : line number that error happened at
|
---|
315 | *
|
---|
316 | * Returns a negative value in error case, on success returns the nodes error
|
---|
317 | * value which is positve (absolute value)
|
---|
318 | */
|
---|
319 | int wc_PeekErrorNode(int idx, const char **file, const char **reason,
|
---|
320 | int *line)
|
---|
321 | {
|
---|
322 | struct wc_error_queue* err;
|
---|
323 |
|
---|
324 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
325 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
326 | return BAD_MUTEX_E;
|
---|
327 | }
|
---|
328 |
|
---|
329 | if (idx < 0) {
|
---|
330 | err = wc_last_node;
|
---|
331 | if (err == NULL) {
|
---|
332 | WOLFSSL_MSG("No Errors in queue");
|
---|
333 | wc_UnLockMutex(&debug_mutex);
|
---|
334 | return BAD_STATE_E;
|
---|
335 | }
|
---|
336 | }
|
---|
337 | else {
|
---|
338 | int i;
|
---|
339 |
|
---|
340 | err = (struct wc_error_queue*)wc_errors;
|
---|
341 | for (i = 0; i < idx; i++) {
|
---|
342 | if (err == NULL) {
|
---|
343 | WOLFSSL_MSG("Error node not found. Bad index?");
|
---|
344 | wc_UnLockMutex(&debug_mutex);
|
---|
345 | return BAD_FUNC_ARG;
|
---|
346 | }
|
---|
347 | err = err->next;
|
---|
348 | }
|
---|
349 | }
|
---|
350 |
|
---|
351 | if (file != NULL) {
|
---|
352 | *file = err->file;
|
---|
353 | }
|
---|
354 |
|
---|
355 | if (reason != NULL) {
|
---|
356 | *reason = err->error;
|
---|
357 | }
|
---|
358 |
|
---|
359 | if (line != NULL) {
|
---|
360 | *line = err->line;
|
---|
361 | }
|
---|
362 |
|
---|
363 | wc_UnLockMutex(&debug_mutex);
|
---|
364 |
|
---|
365 | return err->value;
|
---|
366 | }
|
---|
367 |
|
---|
368 |
|
---|
369 | /* create new error node and add it to the queue
|
---|
370 | * buffers are assumed to be of size WOLFSSL_MAX_ERROR_SZ for this internal
|
---|
371 | * function. debug_mutex should be locked before a call to this function. */
|
---|
372 | int wc_AddErrorNode(int error, int line, char* buf, char* file)
|
---|
373 | {
|
---|
374 |
|
---|
375 | struct wc_error_queue* err;
|
---|
376 |
|
---|
377 | err = (struct wc_error_queue*)XMALLOC(
|
---|
378 | sizeof(struct wc_error_queue), wc_error_heap, DYNAMIC_TYPE_LOG);
|
---|
379 | if (err == NULL) {
|
---|
380 | WOLFSSL_MSG("Unable to create error node for log");
|
---|
381 | return MEMORY_E;
|
---|
382 | }
|
---|
383 | else {
|
---|
384 | int sz;
|
---|
385 |
|
---|
386 | XMEMSET(err, 0, sizeof(struct wc_error_queue));
|
---|
387 | err->heap = wc_error_heap;
|
---|
388 | sz = (int)XSTRLEN(buf);
|
---|
389 | if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
|
---|
390 | sz = WOLFSSL_MAX_ERROR_SZ - 1;
|
---|
391 | }
|
---|
392 | if (sz > 0) {
|
---|
393 | XMEMCPY(err->error, buf, sz);
|
---|
394 | }
|
---|
395 |
|
---|
396 | sz = (int)XSTRLEN(file);
|
---|
397 | if (sz > WOLFSSL_MAX_ERROR_SZ - 1) {
|
---|
398 | sz = WOLFSSL_MAX_ERROR_SZ - 1;
|
---|
399 | }
|
---|
400 | if (sz > 0) {
|
---|
401 | XMEMCPY(err->file, file, sz);
|
---|
402 | }
|
---|
403 |
|
---|
404 | err->value = error;
|
---|
405 | err->line = line;
|
---|
406 |
|
---|
407 | /* make sure is terminated */
|
---|
408 | err->error[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
|
---|
409 | err->file[WOLFSSL_MAX_ERROR_SZ - 1] = '\0';
|
---|
410 |
|
---|
411 |
|
---|
412 | /* since is queue place new node at last of the list */
|
---|
413 | if (wc_last_node == NULL) {
|
---|
414 | /* case of first node added to queue */
|
---|
415 | if (wc_errors != NULL) {
|
---|
416 | /* check for unexpected case before over writing wc_errors */
|
---|
417 | WOLFSSL_MSG("ERROR in adding new node to logging queue!!\n");
|
---|
418 | }
|
---|
419 | else {
|
---|
420 | wc_errors = err;
|
---|
421 | wc_last_node = err;
|
---|
422 | }
|
---|
423 | }
|
---|
424 | else {
|
---|
425 | wc_last_node->next = err;
|
---|
426 | err->prev = wc_last_node;
|
---|
427 | wc_last_node = err;
|
---|
428 | }
|
---|
429 | }
|
---|
430 |
|
---|
431 | return 0;
|
---|
432 | }
|
---|
433 |
|
---|
434 | /* Removes the error node at the specified index.
|
---|
435 | * idx : if -1 then the most recent node is looked at, otherwise search
|
---|
436 | * through queue for node at the given index
|
---|
437 | */
|
---|
438 | void wc_RemoveErrorNode(int idx)
|
---|
439 | {
|
---|
440 | struct wc_error_queue* current;
|
---|
441 |
|
---|
442 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
443 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
444 | return;
|
---|
445 | }
|
---|
446 |
|
---|
447 | if (idx == -1)
|
---|
448 | current = wc_last_node;
|
---|
449 | else {
|
---|
450 | current = (struct wc_error_queue*)wc_errors;
|
---|
451 | for (; current != NULL && idx > 0; idx--)
|
---|
452 | current = current->next;
|
---|
453 | }
|
---|
454 | if (current != NULL) {
|
---|
455 | if (current->prev != NULL)
|
---|
456 | current->prev->next = current->next;
|
---|
457 | if (wc_last_node == current)
|
---|
458 | wc_last_node = current->prev;
|
---|
459 | if (wc_errors == current)
|
---|
460 | wc_errors = current->next;
|
---|
461 | XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
|
---|
462 | }
|
---|
463 |
|
---|
464 | wc_UnLockMutex(&debug_mutex);
|
---|
465 | }
|
---|
466 |
|
---|
467 | #endif /* DEBUG_WOLFSSL || WOLFSSL_NGINX */
|
---|
468 |
|
---|
469 | /* Clears out the list of error nodes.
|
---|
470 | */
|
---|
471 | void wc_ClearErrorNodes(void)
|
---|
472 | {
|
---|
473 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
474 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
475 | return;
|
---|
476 | }
|
---|
477 |
|
---|
478 | /* free all nodes from error queue */
|
---|
479 | {
|
---|
480 | struct wc_error_queue* current;
|
---|
481 | struct wc_error_queue* next;
|
---|
482 |
|
---|
483 | current = (struct wc_error_queue*)wc_errors;
|
---|
484 | while (current != NULL) {
|
---|
485 | next = current->next;
|
---|
486 | XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
|
---|
487 | current = next;
|
---|
488 | }
|
---|
489 | }
|
---|
490 |
|
---|
491 | wc_errors = NULL;
|
---|
492 | wc_last_node = NULL;
|
---|
493 | wc_UnLockMutex(&debug_mutex);
|
---|
494 | }
|
---|
495 |
|
---|
496 | int wc_SetLoggingHeap(void* h)
|
---|
497 | {
|
---|
498 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
499 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
500 | return BAD_MUTEX_E;
|
---|
501 | }
|
---|
502 | wc_error_heap = h;
|
---|
503 | wc_UnLockMutex(&debug_mutex);
|
---|
504 | return 0;
|
---|
505 | }
|
---|
506 |
|
---|
507 | #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)
|
---|
508 | /* empties out the error queue into the file */
|
---|
509 | void wc_ERR_print_errors_fp(FILE* fp)
|
---|
510 | {
|
---|
511 | WOLFSSL_ENTER("wc_ERR_print_errors_fp");
|
---|
512 |
|
---|
513 | if (wc_LockMutex(&debug_mutex) != 0) {
|
---|
514 | WOLFSSL_MSG("Lock debug mutex failed");
|
---|
515 | }
|
---|
516 | else {
|
---|
517 | /* free all nodes from error queue and print them to file */
|
---|
518 | {
|
---|
519 | struct wc_error_queue* current;
|
---|
520 | struct wc_error_queue* next;
|
---|
521 |
|
---|
522 | current = (struct wc_error_queue*)wc_errors;
|
---|
523 | while (current != NULL) {
|
---|
524 | next = current->next;
|
---|
525 | fprintf(fp, "%s\n", current->error);
|
---|
526 | XFREE(current, current->heap, DYNAMIC_TYPE_LOG);
|
---|
527 | current = next;
|
---|
528 | }
|
---|
529 |
|
---|
530 | /* set global pointers to match having been freed */
|
---|
531 | wc_errors = NULL;
|
---|
532 | wc_last_node = NULL;
|
---|
533 | }
|
---|
534 |
|
---|
535 | wc_UnLockMutex(&debug_mutex);
|
---|
536 | }
|
---|
537 | }
|
---|
538 | #endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */
|
---|
539 |
|
---|
540 | #endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */
|
---|
541 |
|
---|