All pastes #457182 Raw Edit

Unnamed

public text v1 · immutable
#457182 ·published 2007-04-25 07:32 UTC
rendered paste body
/* ********************************************
 * 
 * Apliacation to archive multiple files into
 * a single file, without compression
 *
 * (c) Travis Smith [2007]
 * 
 *************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char * HEADER = "NCA v0.2";
char * archive;

struct FILE_OBJ
{
	char * filename;
	char * filedata;
	
	int size;
};
typedef struct FILE_OBJ FileObj;

/*******************************
 *
 * 		ADD
 *
 * 	When writing to the file
 * 	the following sytax is used:
 *	
 *	One time:
 * 	1) One line for the NCA header
 * 	Fpr Every File:
 * 	2) One line for the file name
 * 	3) One line for the size of the file
 * 	4) Binary file data
 *
 * *****************************/
void addToArchive( char * toAdd )
{
	FileObj myFile;
	FILE *in;
	FILE *out;
	myFile.filename = toAdd;
	
	// Tell the user which file is being archived
	printf( "Archiving file: %s\n", toAdd );
	
	// Open the input stream
	in = fopen( toAdd, "rb" );
	
	// Get the size in bytes of the file
	fseek( in, 0, SEEK_END );
	myFile.size = ftell( in );
	
	// Re-open the file
	fclose( in );
	in = fopen( toAdd, "rb" );
	
	// Initialize the filedata string
	myFile.filedata = (char *)malloc( myFile.size +1 );
	
	// Read the file and store its contents
	fread( myFile.filedata, 1, myFile.size, in );
	//printf( "File data read\n" );
	
	// Done reading, close the input stream
	fclose( in );
	
	
	// Open an output stream
	out = fopen( archive, "ab" );
	
	// If the file doesn't exist, create it and write the header
	if ( ftell( out ) == 0 )
		fprintf( out, "%s\n", HEADER );

	// Print the file name and filesize to the stream
	fprintf( out, "%s\n%i\n", myFile.filename, myFile.size ); 
	
	// Print the file data itself to the stream
	fwrite( myFile.filedata, 1, myFile.size, out );

	// Close the stream
	fclose( out );

	// Free allocated memory
	free( myFile.filedata );
	myFile.filedata = NULL;
	
}
/*******************************
 *
 * 		LIST
 *
 * ****************************/
void list( )
{
	FILE * in = fopen( archive, "rb" );
	char * buff = (char *)malloc( 256 );
	
	// Read in the header
	fgets( buff, 256, in );
	printf( "Header: %s", buff );

	printf( "Files archived in %s: \n", archive );

	// Read in the names and file sizes for each file
	while( fgets( buff, 256, in ) )
	{
		buff[ strlen(buff) -1 ] = '\0';
		// Buff is the filename, without the \n
		printf( "\t%s ", buff );
		
		// Read in the file size
		fgets( buff, 256, in );
		printf( "\t%i bytes\n", atoi( buff ) );

		// Skip over the binary data
		fseek( in, atoi( buff ), SEEK_CUR );
	}

	// Free allocated memory
	free( buff ); 
	buff = NULL;
}

/*******************************
 *
 * 		EXTRACT
 *
 * *****************************/
void extractAll( )
{
	FILE * in;		// In stream
	FILE * out;		// Out stream
	char * buff;		// buffer for text data
	char * filedata; 	// Buffer for binary data
	long    size;		// Size of binary data
	
	buff = (char *)malloc(256);
	in   = fopen( archive, "rb" );

	// Read in the header
	fgets( buff, 256, in );
	printf( "Header: %s", buff );

	// Read in the names and file sizes for each
	// And write the filedata to new files
	while( fgets( buff, 256, in ) )
	{
		buff[ strlen(buff) -1 ] = '\0';

		// Tell the user which file is being extracted
		printf( "Extracting: %s\n", buff );
		
		// Create the new file
		out = fopen( buff, "w+b" );
		
		// Get the size of the file
		fgets( buff, 256, in );
		size = atoi( buff );
		
		// Prepare filedata buffer
		filedata = (char *)malloc(size +1);
		
		// Read in the file data
		fread( filedata, 1, size, in );
	
		
		// Wrote the file to disk
		fwrite( filedata, 1, size, out );

		// Close the output file
		fclose( out );

		// Free allocated memory
		free( filedata );
		filedata = NULL;

		
	} // While
	fclose( in );

	// Free allocated memory
	free( buff );
	buff = NULL;
}

/*******************************
 *
 * 		MAIN
 *
 * ******************************/
int main( int argc, char *argv[] )
{
	int i; // Loop counter
	archive = argv[ 2 ];
	
	
	char * usage = "Usage: nca [OPTION] [FILE]...\n"
               "nca saves many files together into a single archive,"
	       "without using any compression\n"
	       "\nExamples: \n"
	       "  nca -a archive.nca foo.txt bar.mp3 \n"
	       "  nca -l archive.nca \n"
	       "  nca -e archive.nca \n"
	       "\nFlags are: \n"
	       "\t-a, --add     \t\tAdd files to archive\n"
	       "\t-e, --extract \t\tExtract all files from archive\n"
	       "\t-l, --list    \t\tList all files within archive\n"
	       "\t-h, --help    \t\tPrint this help menu\n"
	       "\nBugs? Fix it yourself, it's open source :)\n";

	if ( argc < 3 )
	{
		printf( "%s", usage );
		exit(1);
	}
	
	if ( strncmp( argv[ 1 ], "-a", 2 ) == 0 ||
			strncmp( argv[ 1 ], "--add", 5 ) == 0 )
	{
		// Make sure there are enough args
		if ( argc < 4 )
		{
			printf( "%s", usage );
			exit( 1 );
		}

		// Add each file specified to the archive
		for ( i = 3; i < argc; i++ )
			addToArchive( argv[ i ] );
	}
	else if ( strcmp( argv[ 1 ], "-l") == 0 || 
			strcmp( argv[ 1 ], "--list" ) == 0 )
		list( );
	else if ( strcmp( argv[ 1 ], "-e" ) == 0 ||
			strcmp( argv[ 1 ], "--extract" ) == 0 )
		extractAll( );
	else
		printf( "%s", usage );

	return 0;
}