/* * Notification print functions * * Copyright (C) 2008-2022, Joachim Metz * * Refer to AUTHORS for acknowledgements. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include #if defined( HAVE_STDARG_H ) || defined( WINAPI ) #include #elif defined( HAVE_VARARGS_H ) #include #else #error Missing headers stdarg.h and varargs.h #endif #include "libcnotify_definitions.h" #include "libcnotify_libcerror.h" #include "libcnotify_print.h" #include "libcnotify_stream.h" extern FILE *libcnotify_stream; #if defined( HAVE_STDARG_H ) || defined( WINAPI ) #define VARARGS( function, type, argument ) \ function( type argument, ... ) #define VASTART( argument_list, type, name ) \ va_start( argument_list, name ) #define VAEND( argument_list ) \ va_end( argument_list ) #elif defined( HAVE_VARARGS_H ) #define VARARGS( function, type, argument ) \ function( va_alist ) va_dcl #define VASTART( argument_list, type, name ) \ { type name; va_start( argument_list ); name = va_arg( argument_list, type ) #define VAEND( argument_list ) \ va_end( argument_list ); } #endif /* Print a formatted string on the notify stream * Returns the number of printed characters if successful or -1 on error */ int VARARGS( libcnotify_printf, const char *, format ) { va_list argument_list; int print_count = 0; if( libcnotify_stream == NULL ) { return( 0 ); } VASTART( argument_list, char *, format ); #if defined( HAVE_GLIB_H ) g_logv( G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, argument_list ); #else /* TODO handle narrow and wide streams * for multi platform support */ print_count = file_stream_vfprintf( libcnotify_stream, format, argument_list ); #endif VAEND( argument_list ); if( print_count <= -1 ) { return( -1 ); } return( print_count ); } #undef VARARGS #undef VASTART #undef VAEND /* Prints the data as a character on the notify stream * Returns the number of printed characters if successful or -1 on error */ int libcnotify_print_data_as_character( uint8_t data ) { int print_count = 0; if( ( data >= 0x20 ) && ( data <= 0x7e ) ) { print_count = libcnotify_printf( "%c", (char) data ); } else { print_count = libcnotify_printf( "." ); } return( print_count ); } /* Prints the first 16 bytes of data as a characters on the notify stream * Returns the number of printed characters if successful or -1 on error */ int libcnotify_print_data_as_characters( const uint8_t *data, size_t data_size, size_t data_offset ) { int print_count = 0; int total_print_count = 0; if( data == NULL ) { return( -1 ); } while( data_offset < data_size ) { print_count = libcnotify_print_data_as_character( data[ data_offset++ ] ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; if( ( data_offset % 16 == 0 ) || ( data_offset == data_size ) ) { break; } if( data_offset % 8 == 0 ) { print_count = libcnotify_printf( " " ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; } } return( total_print_count ); } /* Prints the first 16 bytes of data as a hexadecimal values on the notify stream * Returns the number of printed characters if successful or -1 on error */ int libcnotify_print_data_as_hexadecimal( const uint8_t *data, size_t data_size, size_t data_offset ) { int print_count = 0; int total_print_count = 0; if( data == NULL ) { return( -1 ); } while( data_offset < data_size ) { print_count = libcnotify_printf( "%.2" PRIx8 " ", data[ data_offset++ ] ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; if( data_offset % 16 == 0 ) { break; } else if( data_offset % 8 == 0 ) { print_count = libcnotify_printf( " " ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; } } while( data_offset % 16 != 0 ) { data_offset++; print_count = libcnotify_printf( " " ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; if( ( data_offset % 8 == 0 ) && ( data_offset % 16 != 0 ) ) { print_count = libcnotify_printf( " " ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; } } return( total_print_count ); } /* Prints the data on the notify stream * Returns the number of printed characters if successful or -1 on error */ int libcnotify_print_data( const uint8_t *data, size_t data_size, uint8_t print_data_flags ) { size_t data_offset = 0; int in_group = 0; int print_count = 0; int total_print_count = 0; if( libcnotify_stream == NULL ) { return( 0 ); } if( data_size > 0 ) { if( data == NULL ) { return( -1 ); } } if( data_size > (size_t) SSIZE_MAX ) { return( -1 ); } while( data_offset < data_size ) { if( ( ( print_data_flags & LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ) != 0 ) && ( data_size >= 32 ) && ( data_offset >= 16 ) && ( data_offset <= ( data_size - 32 ) ) ) { if( ( memory_compare( &( data[ data_offset - 16 ] ), &( data[ data_offset ] ), 16 ) == 0 ) && ( memory_compare( &( data[ data_offset + 16 ] ), &( data[ data_offset ] ), 16 ) == 0 ) ) { if( in_group == 0 ) { print_count = libcnotify_printf( "...\n" ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; in_group = 1; } data_offset += 16; continue; } in_group = 0; } if( data_offset % 16 == 0 ) { print_count = libcnotify_printf( "%.8" PRIzx ": ", data_offset ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; } print_count = libcnotify_print_data_as_hexadecimal( data, data_size, data_offset ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; print_count = libcnotify_printf( " " ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; print_count = libcnotify_print_data_as_characters( data, data_size, data_offset ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; print_count = libcnotify_printf( "\n" ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; data_offset += 16; } print_count = libcnotify_printf( "\n" ); if( print_count <= -1 ) { return( -1 ); } total_print_count += print_count; return( total_print_count ); } /* Prints the backtrace of the error on the notify stream * Returns the number of printed characters if successful or -1 on error */ int libcnotify_print_error_backtrace( libcerror_error_t *error ) { int print_count = 0; if( libcnotify_stream == NULL ) { return( 0 ); } print_count = libcerror_error_backtrace_fprint( error, libcnotify_stream ); return( print_count ); }