rendered paste body#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef long s32;
typedef unsigned long u32;
typedef s32 dword;
typedef short s16;
typedef unsigned short u16;
typedef u16 word;
typedef signed char s8;
typedef unsigned char u8;
typedef u8 byte;
static const byte vpc_signature [] =
{ 'V', 'P', 'C', ' ', 176, 221, 128, 133 };
typedef enum { INVALID, ADD, REMOVE, EXTRACT, LIST, CREATE } VPCCommand;
static void
usage( void ) {
fprintf( stdout, "Usage: vpc CONTAINER_FILE COMMAND [FILE]\n" );
}
static VPCCommand
fetch_cmd( char* arg ) {
// Just check against every string:
if( !strcmp( arg, "add" ) ) return ADD;
if( !strcmp( arg, "remove" ) ) return REMOVE;
if( !strcmp( arg, "extract" ) ) return EXTRACT;
if( !strcmp( arg, "list" ) ) return LIST;
if( !strcmp( arg, "create" ) ) return CREATE;
return INVALID;
}
static int
vpc_insert( FILE* cfile, char const* file ) {
if( !cfile || !file ) return 0;
FILE* datafile = fopen( file, "r" );
if( !datafile ) return 0;
byte b;
for( ; fread( &b, 1, 1, datafile ); fwrite( &b, 1, 1, cfile ) );
return 1;
}
static int
vpc_validate_signature( FILE* file ) {
if( !file ) return 0;
unsigned char read_signature[ 8 ];
if( fread( read_signature, 8, 1, file ) != 1 ) {
fprintf( stderr, "Input/Output error in signature validation\n" );
return 0;
}
for( u32 i = 0; i < 8; ++i )
if( vpc_signature[ i ] != read_signature[ i ] ) {
fprintf( stderr, "Wrong signature\n" );
return 0;
}
return 1;
}
static int
vpc_add( char const* container, char const* file ) {
FILE* cfile = fopen( container, "r" );
if( !cfile ) {
fprintf( stderr, "%s: No such file\n", container );
return 1;
}
if( !vpc_validate_signature( cfile ) ) return 1;
unsigned int first = 0;
if( fread( &first, 4, 1, cfile ) != 1 ) {
fprintf( stderr, "Input/Output error\n" );
fclose( cfile );
return 1;
}
if( first == 0 ) {
unsigned int pos;
fgetpos( cfile, &pos );
pos = pos - 4;
fsetpos( cfile, &pos );
first = 1;
fwrite( &first, 4, 1, cfile );
return vpc_insert( cfile, file );
}
return 0;
}
static int
vpc_remove( char const* container, char const* file ) {
return 0;
}
static int
vpc_extract( char const* container, char const* file ) {
return 0;
}
static int
vpc_list( char const* container ) {
return 0;
}
static int
vpc_create( char const* container ) {
FILE* cfile = fopen( container, "w" );
if( !cfile ) {
fprintf( stderr, "%s: Failed to access\n", container );
return 1;
}
// Write signature:
if( fwrite( vpc_signature, 8, 1, cfile ) != 1 ) {
fprintf( stderr, "Input/Output error\n" );
fclose( cfile );
return 1;
}
// Write first field (0=empty):
dword first = 0;
if( fwrite( &first, sizeof( dword ), 1, cfile ) != 1 ) {
fprintf( stderr, "Input/Output error\n" );
fclose( cfile );
return 1;
}
// Close and exit:
fclose( cfile );
return 0;
}
int
main( int argc, char** argv ) {
// Number of arguments is fix:
if( argc < 3 || argc > 4 ) {
usage();
return 0;
}
// Read the command:
VPCCommand command = fetch_cmd( argv[ 2 ] );
if( command == INVALID ) {
usage();
return 0;
}
// Check number of parameters:
if( ( command == ADD && argc != 4 )
|| ( command == REMOVE && argc != 4 )
|| ( command == EXTRACT && argc != 4 )
|| ( command == LIST && argc != 3 )
|| ( command == CREATE && argc != 3 ) ) {
usage();
return 0;
}
// Do what told to do:
if( command == ADD ) return vpc_add( argv[ 1 ], argv[ 3 ] );
if( command == REMOVE ) return vpc_remove( argv[ 1 ], argv[ 3 ] );
if( command == EXTRACT ) return vpc_extract( argv[ 1 ], argv[ 3 ] );
if( command == LIST ) return vpc_list( argv[ 1 ] );
if( command == CREATE ) return vpc_create( argv[ 1 ] );
return 0;
}