From 32420ad6995ecb1c96b659fc3ba7140c5504522c Mon Sep 17 00:00:00 2001 From: cha0smaster Date: Mon, 13 Feb 2006 01:23:31 +0000 Subject: [PATCH] implement POC of syslog logging handler, make ntfsmount to use it --- ChangeLog | 2 ++ include/ntfs/logging.h | 1 + libntfs/logging.c | 80 ++++++++++++++++++++++++++++++++++++++++-- ntfsprogs/ntfsmount.c | 33 +++++++++++------ 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12ae5c69..611cfb81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -116,6 +116,8 @@ determine using sysconf()). (Anton) - Fix tons of big-endian bugs in mkntfs. (Anton) - ntfsresize, ntfsclone: always use MS_NOATIME. (Szaka) + - Implement simple syslog logging handler (need more work), teach + ntfsmount to use it. (Yura) 10/10/2005 - 1.12.1 - Minor fix to location of mount.ntfs-fuse and mkfs.ntfs. diff --git a/include/ntfs/logging.h b/include/ntfs/logging.h index 552dcc32..0a66dbb3 100644 --- a/include/ntfs/logging.h +++ b/include/ntfs/logging.h @@ -40,6 +40,7 @@ typedef int (ntfs_log_handler)(const char *function, const char *file, int line, void ntfs_log_set_handler(ntfs_log_handler *handler); /* Logging handlers */ +ntfs_log_handler ntfs_log_handler_syslog __attribute__((format(printf, 6, 0))); ntfs_log_handler ntfs_log_handler_fprintf __attribute__((format(printf, 6, 0))); ntfs_log_handler ntfs_log_handler_null __attribute__((format(printf, 6, 0))); ntfs_log_handler ntfs_log_handler_stdout __attribute__((format(printf, 6, 0))); diff --git a/libntfs/logging.c b/libntfs/logging.c index c265a6ae..4997f7f2 100644 --- a/libntfs/logging.c +++ b/libntfs/logging.c @@ -38,6 +38,7 @@ #ifdef HAVE_STDLIB_H #include #endif +#include #include "logging.h" @@ -275,9 +276,11 @@ static const char * ntfs_log_get_prefix(u32 level) */ void ntfs_log_set_handler(ntfs_log_handler *handler) { - if (handler) + if (handler) { ntfs_log.handler = handler; - else + if (handler == ntfs_log_handler_syslog) + openlog("libntfs", LOG_PID, LOG_USER); + } else ntfs_log.handler = ntfs_log_handler_null; } @@ -318,6 +321,79 @@ int ntfs_log_redirect(const char *function, const char *file, } +/** + * ntfs_log_handler_syslog - syslog logging handler + * @function: Function in which the log line occurred + * @file: File in which the log line occurred + * @line: Line number on which the log line occurred + * @level: Level at which the line is logged + * @data: User specified data, possibly specific to a handler + * @format: printf-style formatting string + * @args: Arguments to be formatted + * + * A simple syslog logging handler. Ignores colors. + * + * Returns: -1 Error occurred + * 0 Message wasn't logged + * num Number of output characters + */ +int ntfs_log_handler_syslog(const char *function __attribute__((unused)), + const char *file, __attribute__((unused)) int line, u32 level, + void *data __attribute__((unused)), const char *format, va_list args) +{ + const int reason_size = 128; + static char *reason = NULL; + int ret = 0; + int olderr = errno; + + if (level == NTFS_LOG_LEVEL_REASON) { + if (!reason) + reason = malloc(reason_size); + if (reason) { + memset(reason, 0, reason_size); + return vsnprintf(reason, reason_size, format, args); + } else { + /* Rather than call ourselves, just drop through */ + level = NTFS_LOG_LEVEL_PERROR; + format = "Couldn't create reason"; + args = NULL; + olderr = errno; + } + } + + if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) && + (strchr(file, PATH_SEP))) /* Abbreviate the filename */ + file = strrchr(file, PATH_SEP) + 1; +#if 0 /* FIXME: Implement this all. */ + if (ntfs_log.flags & NTFS_LOG_FLAG_PREFIX) /* Prefix the output */ + ret += fprintf(stream, "%s", ntfs_log_get_prefix(level)); + + if (ntfs_log.flags & NTFS_LOG_FLAG_FILENAME) /* Source filename */ + ret += fprintf(stream, "%s ", file); + + if (ntfs_log.flags & NTFS_LOG_FLAG_LINE) /* Source line number */ + ret += fprintf(stream, "(%d) ", line); + + if ((ntfs_log.flags & NTFS_LOG_FLAG_FUNCTION) || /* Source function */ + (level & NTFS_LOG_LEVEL_TRACE)) + ret += fprintf(stream, "%s(): ", function); + + ret += vfprintf(stream, format, args); + + if (level & NTFS_LOG_LEVEL_PERROR) { + if (reason) + ret += fprintf(stream, " : %s\n", reason); + else + ret += fprintf(stream, " : %s\n", strerror(olderr)); + } +#endif + vsyslog(LOG_NOTICE, format, args); + ret = 1; /* FIXME: caclulate how many bytes had been written. */ + + errno = olderr; + return ret; +} + /** * ntfs_log_handler_fprintf - Basic logging handler * @function: Function in which the log line occurred diff --git a/ntfsprogs/ntfsmount.c b/ntfsprogs/ntfsmount.c index fbadfa4f..8693e72c 100644 --- a/ntfsprogs/ntfsmount.c +++ b/ntfsprogs/ntfsmount.c @@ -51,6 +51,7 @@ #include #endif #include +#include #ifdef HAVE_SETXATTR #include @@ -516,8 +517,8 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx, if (name_type == FILE_NAME_DOS) return 0; if (ntfs_ucstombs(name, name_len, &filename, 0) < 0) { - ntfs_log_error("Skipping unrepresentable file (inode %lld): " - "%s\n", MREF(mref), strerror(errno)); + ntfs_log_error("Skipping unrepresentable filename (inode %lld):" + " %s\n", MREF(mref), strerror(errno)); return 0; } if (ntfs_fuse_is_named_data_stream(filename)) { @@ -1431,11 +1432,13 @@ static int ntfs_fuse_mount(const char *device) static void ntfs_fuse_destroy(void) { if (ctx->vol) { - ntfs_log_debug("Unmounting: %s\n", ctx->vol->vol_name); + ntfs_log_info("Unmounting %s (%s)\n", opts.device, + ctx->vol->vol_name); if (ntfs_umount(ctx->vol, FALSE)) ntfs_log_perror("Failed to unmount volume"); } free(ctx); + free(opts.device); } static void signal_handler(int arg __attribute__((unused))) @@ -1782,7 +1785,6 @@ int main(int argc, char *argv[]) parsed_options = parse_mount_options((opts.options) ? opts.options : ""); if (!parsed_options) { - free(opts.device); ntfs_fuse_destroy(); return 3; } @@ -1790,10 +1792,8 @@ int main(int argc, char *argv[]) /* Mount volume. */ if (ntfs_fuse_mount(opts.device)) { ntfs_fuse_destroy(); - free(opts.device); return 4; } - free(opts.device); /* Create filesystem. */ #if defined(FUSE_VERSION) && (FUSE_VERSION >= 25) if ((fuse_opt_add_arg(&margs, "") == -1 || @@ -1849,12 +1849,23 @@ int main(int argc, char *argv[]) ntfs_fuse_destroy(); return 6; } - if (!ctx->debug && daemon(0, 0)) - ntfs_log_error("Failed to daemonize.\n"); - ntfs_log_info("Mounted: %s\n", ctx->vol->vol_name); + if (!ctx->debug) { + if (daemon(0, 0)) + ntfs_log_error("Failed to daemonize.\n"); + else { + ntfs_log_set_handler(ntfs_log_handler_syslog); + /* Override default libntfs ident. */ + openlog(EXEC_NAME, LOG_PID, LOG_DAEMON); + } + } + ntfs_log_info("Version %s (libntfs %s)\n", VERSION, + ntfs_libntfs_version()); + ntfs_log_info("Mounted %s (%s, label \"%s\", volume version %d.%d)\n", + opts.device, (ctx->ro) ? "RO" : "RW", + ctx->vol->vol_name, ctx->vol->major_ver, + ctx->vol->minor_ver); /* Main loop. */ - if (fuse_loop(fh)) - ntfs_log_error("fuse_loop failed.\n"); + fuse_loop(fh); /* Destroy. */ fuse_destroy(fh); close(ffd);