Rev 52 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#include <spk.h>
CyString g_dir;
#ifdef _WIN32
#include <windows.h>
#include <direct.h>
//#include <shlobj.h>
#else
#include <dirent.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <unistd.h>
#endif
void PrintError ( int err )
{
switch ( err )
{
case CATERR_NODATFILE:
printf ( "No dat file found\n" );
break;
case CATERR_NOCATFILE:
printf ( "Unable to open cat file\n" );
break;
case CATERR_FILEEMPTY:
printf ( "Cat file is empty\n" );
break;
case CATERR_READCAT:
printf ( "Unable to read cat file\n" );
break;
case CATERR_DECRYPT:
printf ( "Unable to decrypt cat file\n" );
break;
case CATERR_MISMATCH:
printf ( "Dat file size mismatch\n" );
break;
}
}
void ListFiles ( CyString filename, CyString searchmask )
{
printf ( "Listing files in %s...", filename.c_str() );
if ( !searchmask.Empty() )
printf ( "(%s)", searchmask.c_str() );
printf ( "\n");
CCatFile catfile;
int err = catfile.Open ( filename, "", CATREAD_CATDECRYPT );
if ( err == CATERR_NONE )
{
printf ( "Opened file\n" );
for ( int i = 0; i < catfile.GetNumFiles(); i++ )
{
SInCatFile *file = catfile.GetFile ( i );
if ( !searchmask.Empty() )
{
if ( !searchmask.WildMatch(file->sFile) )
continue;
}
printf ( "[%9s] %s\n", SPK::GetSizeString(file->lSize).c_str(), file->sFile.c_str() );
}
}
else
PrintError ( err );
}
CyStringList *FindFiles(CyString filepattern)
{
CFileIO File((filepattern.IsIn(":")) ? filepattern : g_dir + "/" + filepattern);
CyStringList *files = File.GetDirIO().DirList(NullString, File.GetFilename());
return files;
}
void ExtractFile ( CyString filename, CyString to, bool preserve )
{
if ( !filename.IsIn ( "::" ) )
return;
CyString catfile = filename.GetToken ( "::", 1, 1 );
CyString filemask = filename.GetToken ( "::", 2, 2 );
CCatFile cat;
int err = cat.Open ( catfile, "", CATREAD_DAT );
if ( err )
{
PrintError ( err );
return;
}
// all files
if ( filemask == "*" )
{
for ( int i = 0; i < cat.GetNumFiles(); i++ )
{
SInCatFile *f = cat.GetFile(i);
if ( !cat.ExtractFile ( f, to ) )
printf ( "Error: %s\n", cat.GetErrorString().c_str() );
else
printf ( "File has been written (%s)\n", cat.ErrorString().c_str() );
}
return;
}
CyStringList *fileList = FindFiles(filemask);
if ( !fileList && fileList->Empty() )
{
printf ( "Error: unable to find any files matching: %s\n", filemask.c_str() );
return;
}
for ( SStringList *fl = fileList->Head(); fl; fl = fl->next )
{
CyString file = fl->str;
if ( !cat.ExtractFile ( file, to, preserve ) )
printf ( "Error: %s\n", cat.GetErrorString().c_str() );
else
printf ( "File has been written (%s)\n", cat.ErrorString().c_str() );
}
delete fileList;
}
void AppendFile ( CyString C_File, CyString filepattern )
{
CyString catfile;
CyString file;
C_File = C_File.FindReplace("\\", "/");
bool doFile = false;
if ( !C_File.IsIn ( "::" ) )
{
catfile = C_File;
doFile = true;
}
else
{
catfile = C_File.GetToken ( "::", 1, 1 );
file = C_File.GetToken ( "::", 2, 2 );
}
CyStringList *list = FindFiles(filepattern);
if ( !list || !list->Count() )
{
printf("Error: no files found to add: %s\n", filepattern.c_str());
return;
}
CCatFile cat;
int err = cat.Open ( catfile, "", CATREAD_CATDECRYPT );
if ( err )
{
delete list;
PrintError ( err );
return;
}
for ( SStringList *fname = list->Head(); fname; fname = fname->next )
{
CyString filename = fname->str;
if ( doFile )
file = filename;
if ( !file.IsIn('.') )
{
if ( file[file.Length() - 1] != '/' )
file += '/';
file += CFileIO(filename).GetFilename();
}
if ( cat.AppendFile ( filename, file ) )
printf ( "File %s has beed added to: %s::%s\n", filename.c_str(), catfile.c_str(), file.c_str() );
else
printf ( "Error: Unable to add file: %s\n", filename.c_str());
}
delete list;
}
void RemoveFile ( CyString C_File, CyString remfile )
{
// first open the cat file
CCatFile cat;
int err = cat.Open ( C_File, "", CATREAD_CATDECRYPT );
if ( err )
{
PrintError ( err );
return;
}
SInCatFile *f = cat.FindData ( remfile );
if ( !f )
{
printf ( "Unable to find %s in cat file\n", remfile.c_str() );
return;
}
if ( cat.RemoveFile ( f ) )
printf ( "File has been removed from archive\n" );
}
void UnpackFile ( CyString file, CyString tofile )
{
CyStringList *list = FindFiles(file);
if ( !list || !list->Count() )
{
printf("Error: no files found to unpack: %s\n", file.c_str());
return;
}
for ( SStringList *fname = list->Head(); fname; fname = fname->next )
{
CyString filename = CFileIO(file).GetDir() + "/" + fname->str;
C_File f(filename);
if ( !f.CheckValidFilePointer() )
printf("Error: %s doesn't exists\n", filename.c_str() );
else if ( !f.ReadFromFile() )
printf("Error: unable to open file: %s\n", filename.c_str() );
else
{
f.UnPCKFile();
if ( tofile.Empty() )
f.ChangeFileExt("xml");
else if ( tofile.Left(2) == "*." )
f.ChangeFileExt(tofile.Right(3));
else
f.SetFilename(tofile);
if ( !f.WriteFilePointer() )
printf("Error: unable to write file: %s\n", tofile.c_str() );
else
printf("%s has been unpacked to %s\n", file.c_str(), f.GetFilename().c_str() );
}
}
delete list;
}
void PackFile ( CyString file, CyString tofile )
{
CyStringList *list = FindFiles(file);
if ( !list || !list->Count() )
{
printf("Error: no files found to pack: %s\n", file.c_str());
return;
}
for ( SStringList *fname = list->Head(); fname; fname = fname->next )
{
CyString filename = CFileIO(file).GetDir() + "/" + fname->str;
C_File f(filename);
if ( !f.CheckValidFilePointer() )
printf("Error: %s doesn't exists\n", filename.c_str() );
else if ( !f.ReadFromFile() )
printf("Error: unable to open file: %s\n", filename.c_str() );
else if ( !f.PCKFile() )
printf("Error: unable to pack file: %s\n", filename.c_str() );
else
{
if ( tofile.Empty() )
{
if ( f.CheckFileExt("bob") )
f.ChangeFileExt("pbb");
else if ( f.CheckFileExt("bod") )
f.ChangeFileExt("pbd");
else
f.ChangeFileExt("pck");
}
else if ( tofile.Left(2) == "*." )
f.ChangeFileExt(tofile.Right(3));
else
f.SetFilename(tofile);
if ( !f.WriteFilePointer() )
printf("Error: unable to write file: %s\n", tofile.c_str() );
else
printf("%s has been packed to %s\n", file.c_str(), f.GetFilename().c_str() );
}
}
delete list;
}
void PrintSyntax(CyString cmd)
{
printf ( "Syntax: %s <flags> [arguments]\n", cmd.c_str() );
printf ( "Flags:\n");
printf ( "\t-l <filename> [filemask]\n");
printf ( "\t\tLists the contents of a cat file, with optional search mask\n");
printf ( "\t-x <catfile::filename> [dir]\n");
printf ( "\t\textracts a file from a cat file to the optional directory\n");
printf ( "\t-xp <catfile::filename> [dir]\n");
printf ( "\t\textracts a file from a cat file to the optional directory, preserves directory structure\n");
printf ( "\t-xa <catfile> [dir]\n");
printf ( "\t\textracts all files to optional directory\n");
printf ( "\t-a <filename> <catfile::tofile>\n");
printf ( "\t\tAdds the file into a cat archive, saves it as <tofile>\n");
printf ( "\t-r <catfile> <file>\n");
printf ( "\t\tRemoves a file from an archive\n");
printf ( "\t-u <filename> <tofile>\n");
printf ( "\t\tUnpacks a file, ie from pck to xml/txt\n");
printf ( "\t-p <filename> <tofile>\n");
printf ( "\t\tPacks a file, ie from xml/txt to pck\n");
}
int main ( int argc, char **argv )
{
printf ( "\nCATPCK Tool V1.21 27/03/2011 (SPK: %.2f) Created by Cycrow\n\n", GetLibraryVersion() );
// parse the cmd name
CyString cmd (argv[0]);
cmd = cmd.FindReplace ( "\\", "/" );
g_dir = cmd.GetToken ( 0, cmd.NumToken('/') - 1, '/' );
cmd = cmd.GetToken ( cmd.NumToken('/'), '/' );
if ( g_dir.Empty() )
{
#ifdef _WIN32
g_dir = CyString(_getcwd(NULL, 0));
#else
g_dir = CyString(getcwd(NULL, 0));
#endif
if ( g_dir.Empty() )
g_dir = "./";
}
if ( argc < 2 )
PrintSyntax(cmd);
else
{
CyString command ( argv[1] );
command.ToLower();
if ( (command == "-l") || (command == "-list") )
{
if ( argc < 3 )
printf ( "Syntax: %s -l <filename> [filemask]\n\tLists the contents of the cat file\n", cmd.c_str() );
else if ( argc < 4 )
ListFiles ( CyString(argv[2]), "" );
else
ListFiles ( CyString(argv[2]), CyString(argv[3]) );
}
else if ( (command == "-x") || (command == "-extract") || (command == "-xp") || (command == "-extractpreserve") )
{
if ( argc < 3 )
printf ( "Syntax: %s %s <catfile::filename> [dir]\n\tExtracts a file from the cat archive\n", cmd.c_str(), command.c_str() );
else if ( argc < 4 )
ExtractFile ( CyString(argv[2]), CyString(""), (command == "-xp" || command == "-extractpreserve") ? true : false );
else
ExtractFile ( CyString(argv[2]), CyString(argv[3]), (command == "-xp" || command == "-extractpreserve") ? true : false );
}
else if ( (command == "-xa") || (command == "-extractall") )
{
if ( argc < 3 )
printf ( "Syntax: %s %s <catfile> [dir]\n\tExtracts all files from the cat archive\n", cmd.c_str(), command.c_str() );
else if ( argc < 4 )
ExtractFile ( CyString(argv[2]) + "::*", CyString(""), true );
else
ExtractFile ( CyString(argv[2]) + "::*", CyString(argv[3]), true );
}
else if ( (command == "-a") || (command == "-append") )
{
if ( argc < 4 )
printf ( "Syntax: %s -a <filename> <catfile::tofile>\n\tAppends a file into the archive\n", cmd.c_str() );
else
AppendFile ( CyString(argv[3]), CyString(argv[2]) );
}
else if ( (command == "-r") || (command == "-remove") )
{
if ( argc < 4 )
printf ( "Syntax: %s -r <catfile> <filename>\n\tRemoves a file from the archive\n", cmd.c_str() );
else
RemoveFile ( CyString(argv[2]), CyString(argv[3]) );
}
else if ( (command == "-u") || (command == "-unpack") )
{
if ( argc < 3 )
printf ( "Syntax: %s -u <filename> [to]\n\tUnpacks a file", cmd.c_str() );
else if ( argc < 4 )
UnpackFile ( CyString(argv[2]), CyString("") );
else
UnpackFile ( CyString(argv[2]), CyString(argv[3]) );
}
else if ( (command == "-p") || (command == "-pack") )
{
if ( argc < 3 )
printf ( "Syntax: %s -p <filename> [to]\n\tPacks a file to .pck", cmd.c_str() );
else if ( argc < 4 )
PackFile ( CyString(argv[2]), CyString("") );
else
PackFile ( CyString(argv[2]), CyString(argv[3]) );
}
else
{
printf("Invalaid flag: %s\n\n", command.c_str());
PrintSyntax(cmd);
}
}
#ifdef _DEBUG
char pause;
printf ( "\n\nPress a key to end\n" );
scanf ( "%c", &pause );
#endif
return 0;
}