blob: ccccbb8fb99eb91ad1517c1ccd24fc5d8b4edd1c
1 | /** |
2 | * logging.c - Centralised logging. Originated from the Linux-NTFS project. |
3 | * |
4 | * Copyright (c) 2005 Richard Russon |
5 | * Copyright (c) 2005-2008 Szabolcs Szakacsits |
6 | * Copyright (c) 2010 Jean-Pierre Andre |
7 | * |
8 | * This program/include file is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License as published |
10 | * by the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program/include file is distributed in the hope that it will be |
14 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty |
15 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program (in the main directory of the NTFS-3G |
20 | * distribution in the file COPYING); if not, write to the Free Software |
21 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | */ |
23 | |
24 | #ifdef HAVE_CONFIG_H |
25 | #include "config.h" |
26 | #endif |
27 | |
28 | #ifdef HAVE_STDIO_H |
29 | #include <stdio.h> |
30 | #endif |
31 | #ifdef HAVE_ERRNO_H |
32 | #include <errno.h> |
33 | #endif |
34 | #ifdef HAVE_STDARG_H |
35 | #include <stdarg.h> |
36 | #endif |
37 | #ifdef HAVE_STRING_H |
38 | #include <string.h> |
39 | #endif |
40 | #ifdef HAVE_STDLIB_H |
41 | #include <stdlib.h> |
42 | #endif |
43 | #ifdef HAVE_SYSLOG_H |
44 | #include <syslog.h> |
45 | #endif |
46 | |
47 | #include "logging.h" |
48 | #include "misc.h" |
49 | |
50 | #ifndef PATH_SEP |
51 | #define PATH_SEP '/' |
52 | #endif |
53 | |
54 | #ifdef DEBUG |
55 | static int tab; |
56 | #endif |
57 | |
58 | /* Some gcc 3.x, 4.[01].X crash with internal compiler error. */ |
59 | #if __GNUC__ <= 3 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 1) |
60 | # define BROKEN_GCC_FORMAT_ATTRIBUTE |
61 | #else |
62 | # define BROKEN_GCC_FORMAT_ATTRIBUTE __attribute__((format(printf, 6, 0))) |
63 | #endif |
64 | |
65 | /** |
66 | * struct ntfs_logging - Control info for the logging system |
67 | * @levels: Bitfield of logging levels |
68 | * @flags: Flags which affect the output style |
69 | * @handler: Function to perform the actual logging |
70 | */ |
71 | struct ntfs_logging { |
72 | u32 levels; |
73 | u32 flags; |
74 | ntfs_log_handler *handler BROKEN_GCC_FORMAT_ATTRIBUTE; |
75 | }; |
76 | |
77 | /** |
78 | * ntfs_log |
79 | * This struct controls all the logging within the library and tools. |
80 | */ |
81 | static struct ntfs_logging ntfs_log = { |
82 | #ifdef DEBUG |
83 | NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE | NTFS_LOG_LEVEL_ENTER | |
84 | NTFS_LOG_LEVEL_LEAVE | |
85 | #endif |
86 | NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET | NTFS_LOG_LEVEL_WARNING | |
87 | NTFS_LOG_LEVEL_ERROR | NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL | |
88 | NTFS_LOG_LEVEL_PROGRESS, |
89 | NTFS_LOG_FLAG_ONLYNAME, |
90 | #ifdef DEBUG |
91 | ntfs_log_handler_outerr |
92 | #else |
93 | ntfs_log_handler_null |
94 | #endif |
95 | }; |
96 | |
97 | |
98 | /** |
99 | * ntfs_log_get_levels - Get a list of the current logging levels |
100 | * |
101 | * Find out which logging levels are enabled. |
102 | * |
103 | * Returns: Log levels in a 32-bit field |
104 | */ |
105 | u32 ntfs_log_get_levels(void) |
106 | { |
107 | return ntfs_log.levels; |
108 | } |
109 | |
110 | /** |
111 | * ntfs_log_set_levels - Enable extra logging levels |
112 | * @levels: 32-bit field of log levels to set |
113 | * |
114 | * Enable one or more logging levels. |
115 | * The logging levels are named: NTFS_LOG_LEVEL_*. |
116 | * |
117 | * Returns: Log levels that were enabled before the call |
118 | */ |
119 | u32 ntfs_log_set_levels(u32 levels) |
120 | { |
121 | u32 old; |
122 | old = ntfs_log.levels; |
123 | ntfs_log.levels |= levels; |
124 | return old; |
125 | } |
126 | |
127 | /** |
128 | * ntfs_log_clear_levels - Disable some logging levels |
129 | * @levels: 32-bit field of log levels to clear |
130 | * |
131 | * Disable one or more logging levels. |
132 | * The logging levels are named: NTFS_LOG_LEVEL_*. |
133 | * |
134 | * Returns: Log levels that were enabled before the call |
135 | */ |
136 | u32 ntfs_log_clear_levels(u32 levels) |
137 | { |
138 | u32 old; |
139 | old = ntfs_log.levels; |
140 | ntfs_log.levels &= (~levels); |
141 | return old; |
142 | } |
143 | |
144 | |
145 | /** |
146 | * ntfs_log_get_flags - Get a list of logging style flags |
147 | * |
148 | * Find out which logging flags are enabled. |
149 | * |
150 | * Returns: Logging flags in a 32-bit field |
151 | */ |
152 | u32 ntfs_log_get_flags(void) |
153 | { |
154 | return ntfs_log.flags; |
155 | } |
156 | |
157 | /** |
158 | * ntfs_log_set_flags - Enable extra logging style flags |
159 | * @flags: 32-bit field of logging flags to set |
160 | * |
161 | * Enable one or more logging flags. |
162 | * The log flags are named: NTFS_LOG_LEVEL_*. |
163 | * |
164 | * Returns: Logging flags that were enabled before the call |
165 | */ |
166 | u32 ntfs_log_set_flags(u32 flags) |
167 | { |
168 | u32 old; |
169 | old = ntfs_log.flags; |
170 | ntfs_log.flags |= flags; |
171 | return old; |
172 | } |
173 | |
174 | /** |
175 | * ntfs_log_clear_flags - Disable some logging styles |
176 | * @flags: 32-bit field of logging flags to clear |
177 | * |
178 | * Disable one or more logging flags. |
179 | * The log flags are named: NTFS_LOG_LEVEL_*. |
180 | * |
181 | * Returns: Logging flags that were enabled before the call |
182 | */ |
183 | u32 ntfs_log_clear_flags(u32 flags) |
184 | { |
185 | u32 old; |
186 | old = ntfs_log.flags; |
187 | ntfs_log.flags &= (~flags); |
188 | return old; |
189 | } |
190 | |
191 | |
192 | /** |
193 | * ntfs_log_get_stream - Default output streams for logging levels |
194 | * @level: Log level |
195 | * |
196 | * By default, urgent messages are sent to "stderr". |
197 | * Other messages are sent to "stdout". |
198 | * |
199 | * Returns: "string" Prefix to be used |
200 | */ |
201 | static FILE * ntfs_log_get_stream(u32 level) |
202 | { |
203 | FILE *stream; |
204 | |
205 | switch (level) { |
206 | case NTFS_LOG_LEVEL_INFO: |
207 | case NTFS_LOG_LEVEL_QUIET: |
208 | case NTFS_LOG_LEVEL_PROGRESS: |
209 | case NTFS_LOG_LEVEL_VERBOSE: |
210 | stream = stdout; |
211 | break; |
212 | |
213 | case NTFS_LOG_LEVEL_DEBUG: |
214 | case NTFS_LOG_LEVEL_TRACE: |
215 | case NTFS_LOG_LEVEL_ENTER: |
216 | case NTFS_LOG_LEVEL_LEAVE: |
217 | case NTFS_LOG_LEVEL_WARNING: |
218 | case NTFS_LOG_LEVEL_ERROR: |
219 | case NTFS_LOG_LEVEL_CRITICAL: |
220 | case NTFS_LOG_LEVEL_PERROR: |
221 | default: |
222 | stream = stderr; |
223 | break; |
224 | } |
225 | |
226 | return stream; |
227 | } |
228 | |
229 | /** |
230 | * ntfs_log_get_prefix - Default prefixes for logging levels |
231 | * @level: Log level to be prefixed |
232 | * |
233 | * Prefixing the logging output can make it easier to parse. |
234 | * |
235 | * Returns: "string" Prefix to be used |
236 | */ |
237 | static const char * ntfs_log_get_prefix(u32 level) |
238 | { |
239 | const char *prefix; |
240 | |
241 | switch (level) { |
242 | case NTFS_LOG_LEVEL_DEBUG: |
243 | prefix = "DEBUG: "; |
244 | break; |
245 | case NTFS_LOG_LEVEL_TRACE: |
246 | prefix = "TRACE: "; |
247 | break; |
248 | case NTFS_LOG_LEVEL_QUIET: |
249 | prefix = "QUIET: "; |
250 | break; |
251 | case NTFS_LOG_LEVEL_INFO: |
252 | prefix = "INFO: "; |
253 | break; |
254 | case NTFS_LOG_LEVEL_VERBOSE: |
255 | prefix = "VERBOSE: "; |
256 | break; |
257 | case NTFS_LOG_LEVEL_PROGRESS: |
258 | prefix = "PROGRESS: "; |
259 | break; |
260 | case NTFS_LOG_LEVEL_WARNING: |
261 | prefix = "WARNING: "; |
262 | break; |
263 | case NTFS_LOG_LEVEL_ERROR: |
264 | prefix = "ERROR: "; |
265 | break; |
266 | case NTFS_LOG_LEVEL_PERROR: |
267 | prefix = "ERROR: "; |
268 | break; |
269 | case NTFS_LOG_LEVEL_CRITICAL: |
270 | prefix = "CRITICAL: "; |
271 | break; |
272 | default: |
273 | prefix = ""; |
274 | break; |
275 | } |
276 | |
277 | return prefix; |
278 | } |
279 | |
280 | |
281 | /** |
282 | * ntfs_log_set_handler - Provide an alternate logging handler |
283 | * @handler: function to perform the logging |
284 | * |
285 | * This alternate handler will be called for all future logging requests. |
286 | * If no @handler is specified, logging will revert to the default handler. |
287 | */ |
288 | void ntfs_log_set_handler(ntfs_log_handler *handler) |
289 | { |
290 | if (handler) { |
291 | ntfs_log.handler = handler; |
292 | #ifdef HAVE_SYSLOG_H |
293 | if (handler == ntfs_log_handler_syslog) |
294 | openlog("ntfs-3g", LOG_PID, LOG_USER); |
295 | #endif |
296 | } else |
297 | ntfs_log.handler = ntfs_log_handler_null; |
298 | } |
299 | |
300 | /** |
301 | * ntfs_log_redirect - Pass on the request to the real handler |
302 | * @function: Function in which the log line occurred |
303 | * @file: File in which the log line occurred |
304 | * @line: Line number on which the log line occurred |
305 | * @level: Level at which the line is logged |
306 | * @data: User specified data, possibly specific to a handler |
307 | * @format: printf-style formatting string |
308 | * @...: Arguments to be formatted |
309 | * |
310 | * This is just a redirector function. The arguments are simply passed to the |
311 | * main logging handler (as defined in the global logging struct @ntfs_log). |
312 | * |
313 | * Returns: -1 Error occurred |
314 | * 0 Message wasn't logged |
315 | * num Number of output characters |
316 | */ |
317 | int ntfs_log_redirect(const char *function, const char *file, |
318 | int line, u32 level, void *data, const char *format, ...) |
319 | { |
320 | int olderr = errno; |
321 | int ret; |
322 | va_list args; |
323 | |
324 | if (!(ntfs_log.levels & level)) /* Don't log this message */ |
325 | return 0; |
326 | |
327 | va_start(args, format); |
328 | errno = olderr; |
329 | ret = ntfs_log.handler(function, file, line, level, data, format, args); |
330 | va_end(args); |
331 | |
332 | errno = olderr; |
333 | return ret; |
334 | } |
335 | |
336 | |
337 | /** |
338 | * ntfs_log_handler_syslog - syslog logging handler |
339 | * @function: Function in which the log line occurred |
340 | * @file: File in which the log line occurred |
341 | * @line: Line number on which the log line occurred |
342 | * @level: Level at which the line is logged |
343 | * @data: User specified data, possibly specific to a handler |
344 | * @format: printf-style formatting string |
345 | * @args: Arguments to be formatted |
346 | * |
347 | * A simple syslog logging handler. Ignores colors. |
348 | * |
349 | * Returns: -1 Error occurred |
350 | * 0 Message wasn't logged |
351 | * num Number of output characters |
352 | */ |
353 | |
354 | |
355 | #ifdef HAVE_SYSLOG_H |
356 | |
357 | #define LOG_LINE_LEN 512 |
358 | |
359 | int ntfs_log_handler_syslog(const char *function __attribute__((unused)), |
360 | const char *file __attribute__((unused)), |
361 | int line __attribute__((unused)), u32 level, |
362 | void *data __attribute__((unused)), |
363 | const char *format, va_list args) |
364 | { |
365 | char logbuf[LOG_LINE_LEN]; |
366 | int ret, olderr = errno; |
367 | |
368 | #ifndef DEBUG |
369 | if ((level & NTFS_LOG_LEVEL_PERROR) && errno == ENOSPC) |
370 | return 1; |
371 | #endif |
372 | ret = vsnprintf(logbuf, LOG_LINE_LEN, format, args); |
373 | if (ret < 0) { |
374 | vsyslog(LOG_NOTICE, format, args); |
375 | ret = 1; |
376 | goto out; |
377 | } |
378 | |
379 | if ((LOG_LINE_LEN > ret + 3) && (level & NTFS_LOG_LEVEL_PERROR)) { |
380 | strncat(logbuf, ": ", LOG_LINE_LEN - ret - 1); |
381 | strncat(logbuf, strerror(olderr), LOG_LINE_LEN - (ret + 3)); |
382 | ret = strlen(logbuf); |
383 | } |
384 | |
385 | syslog(LOG_NOTICE, "%s", logbuf); |
386 | out: |
387 | errno = olderr; |
388 | return ret; |
389 | } |
390 | #endif |
391 | |
392 | /* |
393 | * Early logging before the logs are redirected |
394 | * |
395 | * (not quite satisfactory : this appears before the ntfs-g banner, |
396 | * and with a different pid) |
397 | */ |
398 | |
399 | void ntfs_log_early_error(const char *format, ...) |
400 | { |
401 | va_list args; |
402 | |
403 | va_start(args, format); |
404 | #ifdef HAVE_SYSLOG_H |
405 | openlog("ntfs-3g", LOG_PID, LOG_USER); |
406 | ntfs_log_handler_syslog(NULL, NULL, 0, |
407 | NTFS_LOG_LEVEL_ERROR, NULL, |
408 | format, args); |
409 | #else |
410 | vfprintf(stderr,format,args); |
411 | #endif |
412 | va_end(args); |
413 | } |
414 | |
415 | /** |
416 | * ntfs_log_handler_fprintf - Basic logging handler |
417 | * @function: Function in which the log line occurred |
418 | * @file: File in which the log line occurred |
419 | * @line: Line number on which the log line occurred |
420 | * @level: Level at which the line is logged |
421 | * @data: User specified data, possibly specific to a handler |
422 | * @format: printf-style formatting string |
423 | * @args: Arguments to be formatted |
424 | * |
425 | * A simple logging handler. This is where the log line is finally displayed. |
426 | * It is more likely that you will want to set the handler to either |
427 | * ntfs_log_handler_outerr or ntfs_log_handler_stderr. |
428 | * |
429 | * Note: For this handler, @data is a pointer to a FILE output stream. |
430 | * If @data is NULL, nothing will be displayed. |
431 | * |
432 | * Returns: -1 Error occurred |
433 | * 0 Message wasn't logged |
434 | * num Number of output characters |
435 | */ |
436 | int ntfs_log_handler_fprintf(const char *function, const char *file, |
437 | int line, u32 level, void *data, const char *format, va_list args) |
438 | { |
439 | #ifdef DEBUG |
440 | int i; |
441 | #endif |
442 | int ret = 0; |
443 | int olderr = errno; |
444 | FILE *stream; |
445 | |
446 | if (!data) /* Interpret data as a FILE stream. */ |
447 | return 0; /* If it's NULL, we can't do anything. */ |
448 | stream = (FILE*)data; |
449 | |
450 | #ifdef DEBUG |
451 | if (level == NTFS_LOG_LEVEL_LEAVE) { |
452 | if (tab) |
453 | tab--; |
454 | return 0; |
455 | } |
456 | |
457 | for (i = 0; i < tab; i++) |
458 | ret += fprintf(stream, " "); |
459 | #endif |
460 | if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) && |
461 | (strchr(file, PATH_SEP))) /* Abbreviate the filename */ |
462 | file = strrchr(file, PATH_SEP) + 1; |
463 | |
464 | if (ntfs_log.flags & NTFS_LOG_FLAG_PREFIX) /* Prefix the output */ |
465 | ret += fprintf(stream, "%s", ntfs_log_get_prefix(level)); |
466 | |
467 | if (ntfs_log.flags & NTFS_LOG_FLAG_FILENAME) /* Source filename */ |
468 | ret += fprintf(stream, "%s ", file); |
469 | |
470 | if (ntfs_log.flags & NTFS_LOG_FLAG_LINE) /* Source line number */ |
471 | ret += fprintf(stream, "(%d) ", line); |
472 | |
473 | if ((ntfs_log.flags & NTFS_LOG_FLAG_FUNCTION) || /* Source function */ |
474 | (level & NTFS_LOG_LEVEL_TRACE) || (level & NTFS_LOG_LEVEL_ENTER)) |
475 | ret += fprintf(stream, "%s(): ", function); |
476 | |
477 | ret += vfprintf(stream, format, args); |
478 | |
479 | if (level & NTFS_LOG_LEVEL_PERROR) |
480 | ret += fprintf(stream, ": %s\n", strerror(olderr)); |
481 | |
482 | #ifdef DEBUG |
483 | if (level == NTFS_LOG_LEVEL_ENTER) |
484 | tab++; |
485 | #endif |
486 | fflush(stream); |
487 | errno = olderr; |
488 | return ret; |
489 | } |
490 | |
491 | /** |
492 | * ntfs_log_handler_null - Null logging handler (no output) |
493 | * @function: Function in which the log line occurred |
494 | * @file: File in which the log line occurred |
495 | * @line: Line number on which the log line occurred |
496 | * @level: Level at which the line is logged |
497 | * @data: User specified data, possibly specific to a handler |
498 | * @format: printf-style formatting string |
499 | * @args: Arguments to be formatted |
500 | * |
501 | * This handler produces no output. It provides a way to temporarily disable |
502 | * logging, without having to change the levels and flags. |
503 | * |
504 | * Returns: 0 Message wasn't logged |
505 | */ |
506 | int ntfs_log_handler_null(const char *function __attribute__((unused)), const char *file __attribute__((unused)), |
507 | int line __attribute__((unused)), u32 level __attribute__((unused)), void *data __attribute__((unused)), |
508 | const char *format __attribute__((unused)), va_list args __attribute__((unused))) |
509 | { |
510 | return 0; |
511 | } |
512 | |
513 | /** |
514 | * ntfs_log_handler_stdout - All logs go to stdout |
515 | * @function: Function in which the log line occurred |
516 | * @file: File in which the log line occurred |
517 | * @line: Line number on which the log line occurred |
518 | * @level: Level at which the line is logged |
519 | * @data: User specified data, possibly specific to a handler |
520 | * @format: printf-style formatting string |
521 | * @args: Arguments to be formatted |
522 | * |
523 | * Display a log message to stdout. |
524 | * |
525 | * Note: For this handler, @data is a pointer to a FILE output stream. |
526 | * If @data is NULL, then stdout will be used. |
527 | * |
528 | * Note: This function calls ntfs_log_handler_fprintf to do the main work. |
529 | * |
530 | * Returns: -1 Error occurred |
531 | * 0 Message wasn't logged |
532 | * num Number of output characters |
533 | */ |
534 | int ntfs_log_handler_stdout(const char *function, const char *file, |
535 | int line, u32 level, void *data, const char *format, va_list args) |
536 | { |
537 | if (!data) |
538 | data = stdout; |
539 | |
540 | return ntfs_log_handler_fprintf(function, file, line, level, data, format, args); |
541 | } |
542 | |
543 | /** |
544 | * ntfs_log_handler_outerr - Logs go to stdout/stderr depending on level |
545 | * @function: Function in which the log line occurred |
546 | * @file: File in which the log line occurred |
547 | * @line: Line number on which the log line occurred |
548 | * @level: Level at which the line is logged |
549 | * @data: User specified data, possibly specific to a handler |
550 | * @format: printf-style formatting string |
551 | * @args: Arguments to be formatted |
552 | * |
553 | * Display a log message. The output stream will be determined by the log |
554 | * level. |
555 | * |
556 | * Note: For this handler, @data is a pointer to a FILE output stream. |
557 | * If @data is NULL, the function ntfs_log_get_stream will be called |
558 | * |
559 | * Note: This function calls ntfs_log_handler_fprintf to do the main work. |
560 | * |
561 | * Returns: -1 Error occurred |
562 | * 0 Message wasn't logged |
563 | * num Number of output characters |
564 | */ |
565 | int ntfs_log_handler_outerr(const char *function, const char *file, |
566 | int line, u32 level, void *data, const char *format, va_list args) |
567 | { |
568 | if (!data) |
569 | data = ntfs_log_get_stream(level); |
570 | |
571 | return ntfs_log_handler_fprintf(function, file, line, level, data, format, args); |
572 | } |
573 | |
574 | /** |
575 | * ntfs_log_handler_stderr - All logs go to stderr |
576 | * @function: Function in which the log line occurred |
577 | * @file: File in which the log line occurred |
578 | * @line: Line number on which the log line occurred |
579 | * @level: Level at which the line is logged |
580 | * @data: User specified data, possibly specific to a handler |
581 | * @format: printf-style formatting string |
582 | * @args: Arguments to be formatted |
583 | * |
584 | * Display a log message to stderr. |
585 | * |
586 | * Note: For this handler, @data is a pointer to a FILE output stream. |
587 | * If @data is NULL, then stdout will be used. |
588 | * |
589 | * Note: This function calls ntfs_log_handler_fprintf to do the main work. |
590 | * |
591 | * Returns: -1 Error occurred |
592 | * 0 Message wasn't logged |
593 | * num Number of output characters |
594 | */ |
595 | int ntfs_log_handler_stderr(const char *function, const char *file, |
596 | int line, u32 level, void *data, const char *format, va_list args) |
597 | { |
598 | if (!data) |
599 | data = stderr; |
600 | |
601 | return ntfs_log_handler_fprintf(function, file, line, level, data, format, args); |
602 | } |
603 | |
604 | |
605 | /** |
606 | * ntfs_log_parse_option - Act upon command line options |
607 | * @option: Option flag |
608 | * |
609 | * Delegate some of the work of parsing the command line. All the options begin |
610 | * with "--log-". Options cause log levels to be enabled in @ntfs_log (the |
611 | * global logging structure). |
612 | * |
613 | * Note: The "colour" option changes the logging handler. |
614 | * |
615 | * Returns: TRUE Option understood |
616 | * FALSE Invalid log option |
617 | */ |
618 | BOOL ntfs_log_parse_option(const char *option) |
619 | { |
620 | if (strcmp(option, "--log-debug") == 0) { |
621 | ntfs_log_set_levels(NTFS_LOG_LEVEL_DEBUG); |
622 | return TRUE; |
623 | } else if (strcmp(option, "--log-verbose") == 0) { |
624 | ntfs_log_set_levels(NTFS_LOG_LEVEL_VERBOSE); |
625 | return TRUE; |
626 | } else if (strcmp(option, "--log-quiet") == 0) { |
627 | ntfs_log_clear_levels(NTFS_LOG_LEVEL_QUIET); |
628 | return TRUE; |
629 | } else if (strcmp(option, "--log-trace") == 0) { |
630 | ntfs_log_set_levels(NTFS_LOG_LEVEL_TRACE); |
631 | return TRUE; |
632 | } |
633 | |
634 | ntfs_log_debug("Unknown logging option '%s'\n", option); |
635 | return FALSE; |
636 | } |
637 | |
638 |