#if HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ #if HAVE_STRING_H #include #endif /* HAVE_STRING_H */ #if HAVE_STDIO_H #include #endif /* HAVE_STDIO_H */ #if HAVE_STDARG_H #include /* ANSI C header file */ #endif /* HAVE_STDARG_H */ #if HAVE_STDLIB_H #include #endif /* HAVE_STDLIB_H */ #if HAVE_ERRNO_H #include #endif /* HAVE_ERRNO_H */ #define MAXLINE 4096 #include "logger.h" struct logger *logger = NULL; struct logger { /** The name of the file that is being logged to. */ char *log_file; /** * The file descriptor being written to. * NULL if there is no current file being written to. */ FILE *fd; /** * A flag telling if this logger has had any data written to it * since it was opened. */ int used; /** * A flag to tell if the logger is currently recording data * passed to it. * 1 if it is recording. * 0 if it is not. */ int recording; }; struct logger *logger_create ( void ) { struct logger *log; log = (struct logger*)malloc ( sizeof ( struct logger ) ); if ( !log ) return NULL; log->log_file = NULL; log->fd = NULL; log->used = 0; log->recording = 1; return log; } int logger_destroy ( struct logger *log ) { if ( !log ) return 0; if ( log->log_file ) { free ( log->log_file ); log->log_file = NULL; } if ( log->fd ) { fclose ( log->fd ); log->fd = NULL; } free ( log ); log = NULL; return 0; } /** * This is used to close or discard the data was being used to * write to a file, descriptor or whatever else. * After this is called, another file or descriptor can be setup, * and the logger should use that from then on. * * \param log * The logger context. * * \return * 0 on success, or -1 on error. */ static int logger_close_writer ( struct logger *log ) { if ( !log ) return -1; /* A file is being written to */ if ( log->log_file ) { free ( log->log_file ); log->log_file = NULL; fclose ( log->fd ); log->fd = NULL; /* A descriptor was passed in, discard it */ } else if ( log->fd ) { log->fd = NULL; } log->used = 0; return 0; } int logger_set_file ( struct logger *log, const char *file ) { if ( !log ) return -1; if ( !file ) return -1; /* prepare for writing */ if ( logger_close_writer ( log ) == -1 ) return -1; log->fd = fopen ( file, "w" ); /* If the open failed, just return */ if ( !log->fd ) { printf ( "Error: Could not open file %s for writing\n", file ); return -1; } log->log_file = strdup ( file ); return 0; } int logger_set_fd ( struct logger *log, FILE *fd ) { if ( !log ) return -1; if ( !fd ) return -1; /* prepare for writing */ if ( logger_close_writer ( log ) == -1 ) return -1; log->fd = fd; return 0; } int logger_get_file ( struct logger *log, char **file ) { if ( !file ) return -1; *file = 0; if ( !log ) return -1; *file = log->log_file; return 0; } int logger_write_pos ( struct logger *log, const char *file, int line, const char *fmt, ...) { va_list ap; char va_buf[MAXLINE]; if ( !log ) return -1; /* It's OK to write nothing */ if ( !fmt ) return 0; if ( !log->recording ) return 0; /* Get the buffer with format */ va_start(ap, fmt); #ifdef HAVE_VSNPRINTF vsnprintf(va_buf, sizeof(va_buf), fmt, ap); /* this is safe */ #else vsprintf(va_buf, fmt, ap); /* this is not safe */ #endif va_end(ap); fprintf ( log->fd, "%s:%d %s\n", file, line, va_buf ); log->used = 1; return 0; } int logger_has_recv_data ( struct logger *log, int *has_recv_data ) { if ( !has_recv_data ) return -1; *has_recv_data = 0; if ( !log ) return 0; *has_recv_data = log->used; return 0; } int logger_set_record ( struct logger *log, int record ) { if ( !log ) return -1; if ( record == 1 ) log->recording = 1; if ( record == 0 ) log->recording = 0; return 0; } int logger_is_recording ( struct logger *log ) { if ( !log ) return -1; return log->recording; }