/* ******************************************** * * 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;}