File: /home/django/libpff/pfftools/pffinfo.c
/*
* Shows information obtained from a Personal Folder File (OST, PAB and PST)
*
* Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include <common.h>
#include <memory.h>
#include <system_string.h>
#include <types.h>
#include <stdio.h>
#if defined( HAVE_UNISTD_H )
#include <unistd.h>
#endif
#if defined( HAVE_STDLIB_H ) || defined( WINAPI )
#include <stdlib.h>
#endif
#include "info_handle.h"
#include "pffinput.h"
#include "pfftools_getopt.h"
#include "pfftools_libcerror.h"
#include "pfftools_libclocale.h"
#include "pfftools_libcnotify.h"
#include "pfftools_libpff.h"
#include "pfftools_output.h"
#include "pfftools_signal.h"
#include "pfftools_unused.h"
info_handle_t *pffinfo_info_handle = NULL;
int pffinfo_abort = 0;
/* Prints the executable usage information
*/
void usage_fprint(
FILE *stream )
{
if( stream == NULL )
{
return;
}
fprintf( stream, "Use pffinfo to determine information about a Personal Folder File (OST, PAB\n"
"and PST).\n\n" );
fprintf( stream, "Usage: pffinfo [ -c codepage ] [ -ahvV ] source\n\n" );
fprintf( stream, "\tsource: the source file\n\n" );
fprintf( stream, "\t-a: shows allocation information\n" );
fprintf( stream, "\t-c: codepage of ASCII strings, options: ascii, windows-874,\n"
"\t windows-932, windows-936, windows-949, windows-950,\n"
"\t windows-1250, windows-1251, windows-1252 (default),\n"
"\t windows-1253, windows-1254, windows-1255, windows-1256\n"
"\t windows-1257 or windows-1258\n" );
fprintf( stream, "\t-h: shows this help\n" );
fprintf( stream, "\t-v: verbose output to stderr\n" );
fprintf( stream, "\t-V: print version\n" );
}
/* Signal handler for pffinfo
*/
void pffinfo_signal_handler(
pfftools_signal_t signal PFFTOOLS_ATTRIBUTE_UNUSED )
{
libcerror_error_t *error = NULL;
static char *function = "pffinfo_signal_handler";
PFFTOOLS_UNREFERENCED_PARAMETER( signal )
pffinfo_abort = 1;
if( pffinfo_info_handle != NULL )
{
if( info_handle_signal_abort(
pffinfo_info_handle,
&error ) != 1 )
{
libcnotify_printf(
"%s: unable to signal info handle to abort.\n",
function );
libcnotify_print_error_backtrace(
error );
libcerror_error_free(
&error );
}
}
/* Force stdin to close otherwise any function reading it will remain blocked
*/
#if defined( WINAPI ) && !defined( __CYGWIN__ )
if( _close(
0 ) != 0 )
#else
if( close(
0 ) != 0 )
#endif
{
libcnotify_printf(
"%s: unable to close stdin.\n",
function );
}
}
/* The main program
*/
#if defined( HAVE_WIDE_SYSTEM_CHARACTER )
int wmain( int argc, wchar_t * const argv[] )
#else
int main( int argc, char * const argv[] )
#endif
{
libcerror_error_t *error = NULL;
system_character_t *option_ascii_codepage = NULL;
system_character_t *source = NULL;
char *program = "pffinfo";
system_integer_t option = 0;
uint8_t show_allocation_information = 0;
int result = 0;
int verbose = 0;
libcnotify_stream_set(
stderr,
NULL );
libcnotify_verbose_set(
1 );
if( libclocale_initialize(
"pfftools",
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize locale values.\n" );
goto on_error;
}
if( pfftools_output_initialize(
_IONBF,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize output settings.\n" );
goto on_error;
}
pfftools_output_version_fprint(
stdout,
program );
while( ( option = pfftools_getopt(
argc,
argv,
_SYSTEM_STRING( "ac:hvV" ) ) ) != (system_integer_t) -1 )
{
switch( option )
{
case (system_integer_t) '?':
default:
fprintf(
stderr,
"Invalid argument: %" PRIs_SYSTEM "\n",
argv[ optind - 1 ] );
usage_fprint(
stdout );
return( EXIT_FAILURE );
case (system_integer_t) 'a':
show_allocation_information = 1;
break;
case (system_integer_t) 'c':
option_ascii_codepage = optarg;
break;
case (system_integer_t) 'h':
usage_fprint(
stdout );
return( EXIT_SUCCESS );
case (system_integer_t) 'v':
verbose = 1;
break;
case (system_integer_t) 'V':
pfftools_output_copyright_fprint(
stdout );
return( EXIT_SUCCESS );
}
}
if( optind == argc )
{
fprintf(
stderr,
"Missing source file.\n" );
usage_fprint(
stdout );
return( EXIT_FAILURE );
}
source = argv[ optind ];
libcnotify_verbose_set(
verbose );
libpff_notify_set_stream(
stderr,
NULL );
libpff_notify_set_verbose(
verbose );
if( info_handle_initialize(
&pffinfo_info_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to initialize info handle.\n" );
goto on_error;
}
if( option_ascii_codepage != NULL )
{
result = info_handle_set_ascii_codepage(
pffinfo_info_handle,
option_ascii_codepage,
&error );
if( result == -1 )
{
fprintf(
stderr,
"Unable to set ASCII codepage in info handle.\n" );
goto on_error;
}
else if( result == 0 )
{
fprintf(
stderr,
"Unsupported ASCII codepage defaulting to: windows-1252.\n" );
}
}
/* TODO
if( pfftools_signal_attach(
pffinfo_signal_handler,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to attach signal handler.\n" );
libcnotify_print_error_backtrace(
error );
libcerror_error_free(
&error );
}
*/
if( info_handle_open_input(
pffinfo_info_handle,
source,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to open: %" PRIs_SYSTEM ".\n",
source );
goto on_error;
}
if( info_handle_file_fprint(
pffinfo_info_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to print file information.\n" );
goto on_error;
}
if( info_handle_message_store_fprint(
pffinfo_info_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to print file stream and storage items.\n" );
goto on_error;
}
if( show_allocation_information != 0 )
{
if( info_handle_unallocated_blocks_fprint(
pffinfo_info_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to print file unallocated blocks.\n" );
goto on_error;
}
}
/* TODO
if( pfftools_signal_detach(
&error ) != 1 )
{
fprintf(
stderr,
"Unable to detach signal handler.\n" );
libcnotify_print_error_backtrace(
error );
libcerror_error_free(
&error );
}
*/
if( info_handle_close(
pffinfo_info_handle,
&error ) != 0 )
{
fprintf(
stderr,
"Unable to close info handle.\n" );
goto on_error;
}
if( info_handle_free(
&pffinfo_info_handle,
&error ) != 1 )
{
fprintf(
stderr,
"Unable to free info handle.\n" );
goto on_error;
}
return( EXIT_SUCCESS );
on_error:
if( error != NULL )
{
libcnotify_print_error_backtrace(
error );
libcerror_error_free(
&error );
}
if( pffinfo_info_handle != NULL )
{
info_handle_close(
pffinfo_info_handle,
NULL );
info_handle_free(
&pffinfo_info_handle,
NULL );
}
return( EXIT_FAILURE );
}