Subversion Repositories spk

Rev

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