campo-sirio/xvaga/agasys.cpp
alex f029de3450 Patch level : AGA 02.00 314
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :
Riportata la versione Partners 2.0 patch 314


git-svn-id: svn://10.65.10.50/trunk@10444 c028cbd2-c16b-5b4b-a496-9718f37d4682
2002-07-30 14:11:47 +00:00

464 lines
11 KiB
C++
Executable File

#include "wxinc.h"
#include <fstream.h>
#include "agasys.h"
bool aga_get_host_name(char* name, int maxlen)
{
wxString str = wxGetHostName();
const int len = str.Length();
strncpy(name, str, maxlen);
name[maxlen-1] = '\0';
return len > 0;
}
bool aga_get_user_name(char* name, int maxlen)
{
wxString str = wxGetUserId();
str.MakeUpper();
const int len = str.Length();
strncpy(name, str, maxlen);
name[maxlen-1] = '\0';
return len > 0;
}
void aga_log(const char* fmt, ...)
{
static bool bStarted = false;
FILE* log = fopen("aga.log", bStarted ? "a" : "w");
va_list argptr;
va_start(argptr,fmt);
vfprintf(log, fmt, argptr);
va_end(argptr);
fprintf(log, "\n");
fclose(log);
bStarted = true;
}
///////////////////////////////////////////////////////////
// Unzip support
///////////////////////////////////////////////////////////
#include <wx/fs_zip.h>
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <../src/zlib/zlib.h>
#include <../src/common/unzip.h>
class WXDLLEXPORT wxAgaZipFSHandler : public wxFileSystemHandler
{
public:
wxAgaZipFSHandler();
virtual bool CanOpen(const wxString& location);
virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location);
virtual wxString FindFirst(const wxString& spec, int flags = 0);
virtual wxString FindNext();
~wxAgaZipFSHandler();
private:
// these vars are used by FindFirst/Next:
unzFile m_Archive;
wxString m_Pattern, m_BaseDir, m_ZipFile;
bool m_AllowDirs, m_AllowFiles;
wxString DoFind();
};
wxAgaZipFSHandler::wxAgaZipFSHandler() : wxFileSystemHandler()
{
m_Archive = NULL;
m_ZipFile = m_Pattern = m_BaseDir = wxEmptyString;
m_AllowDirs = m_AllowFiles = TRUE;
}
wxAgaZipFSHandler::~wxAgaZipFSHandler()
{
if (m_Archive)
unzClose(m_Archive);
}
bool wxAgaZipFSHandler::CanOpen(const wxString& location)
{
wxString p = GetProtocol(location);
return (p == wxT("zip"));
}
wxFSFile* wxAgaZipFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), const wxString& location)
{
return NULL;
}
wxString wxAgaZipFSHandler::FindFirst(const wxString& spec, int flags)
{
wxString right = GetRightLocation(spec);
wxString left = GetLeftLocation(spec);
if (right.Last() == wxT('/')) right.RemoveLast();
if (m_Archive)
{
unzClose(m_Archive);
m_Archive = NULL;
}
if (GetProtocol(left) != wxT("file"))
return wxEmptyString;
switch (flags)
{
case wxFILE:
m_AllowDirs = FALSE, m_AllowFiles = TRUE; break;
case wxDIR:
m_AllowDirs = TRUE, m_AllowFiles = FALSE; break;
default:
m_AllowDirs = m_AllowFiles = TRUE; break;
}
m_ZipFile = left;
m_Archive = (void*) unzOpen(m_ZipFile.mb_str());
m_Pattern = right.AfterLast(wxT('/'));
m_BaseDir = right.BeforeLast(wxT('/'));
if (m_Archive)
{
if (unzGoToFirstFile((unzFile)m_Archive) != UNZ_OK)
{
unzClose((unzFile)m_Archive);
m_Archive = NULL;
}
else
return DoFind();
}
return wxEmptyString;
}
wxString wxAgaZipFSHandler::FindNext()
{
if (!m_Archive) return wxEmptyString;
return DoFind();
}
wxString wxAgaZipFSHandler::DoFind()
{
const size_t nBufSize = 1024;
char* namebuf = new char[nBufSize]; // char, not wxChar!
char *c;
wxString fn, dir, name;
wxString match = wxEmptyString;
bool wasdir;
while (match == wxEmptyString)
{
unzGetCurrentFileInfo(m_Archive, NULL, namebuf, nBufSize, NULL, 0, NULL, 0);
for (c = namebuf; *c; c++) if (*c == wxT('\\')) *c = wxT('/');
fn = namebuf;
if (fn.Length() > 0 && fn.Last() == wxT('/'))
{
fn.RemoveLast();
wasdir = TRUE;
}
else wasdir = FALSE;
name = fn.AfterLast(wxT('/'));
dir = fn.BeforeLast(wxT('/'));
if (m_AllowDirs || dir == m_BaseDir)
{
if (m_AllowFiles && !wasdir && wxMatchWild(m_Pattern, name, FALSE))
match = m_ZipFile + wxT("#zip:") + fn;
if (m_AllowDirs && wasdir && wxMatchWild(m_Pattern, name, FALSE))
match = m_ZipFile + wxT("#zip:") + fn;
}
if (unzGoToNextFile(m_Archive) != UNZ_OK)
{
unzClose(m_Archive);
m_Archive = NULL;
break;
}
}
delete [] namebuf;
return match;
}
bool aga_unzip(const char* zipfile, const char* destdir)
{
wxString str = zipfile;
str += "#zip:*";
wxAgaZipFSHandler fs;
wxString strInFile = fs.FindFirst(str, 0);
while (!strInFile.IsEmpty())
{
const int nDiesis = strInFile.Find('#');
const wxString strFileName = strInFile.Mid(nDiesis+5);
wxZipInputStream fin(zipfile, strFileName);
wxString strOutFile = destdir;
strOutFile += '/';
strOutFile += strFileName;
wxString strPath;
::wxSplitPath(strOutFile, &strPath, NULL, NULL);
if (!::wxDirExists(strPath))
::wxMkdir(strPath);
wxFFileOutputStream fout(strOutFile);
fout.Write(fin);
strInFile = fs.FindNext();
}
return TRUE;
}
///////////////////////////////////////////////////////////
// Zip support
///////////////////////////////////////////////////////////
#include <wx/zstream.h>
#pragma pack(2)
struct ZipLocalFileHeader
{
unsigned short nVersionNeeded;
unsigned short nFlags;
unsigned short nMethod;
unsigned short nLastModTime;
unsigned short nLastModDate;
unsigned long dwCRC;
unsigned long dwCompressedSize;
unsigned long dwUncompressedSize;
unsigned short nNameLength;
unsigned short nExtraLength;
};
struct ZipDirectoryFileHeader
{
unsigned short nVersionUsed;
ZipLocalFileHeader zlfh;
unsigned short nCommentLength;
unsigned short nStartDisk;
unsigned short nInternalAttr;
unsigned long nExternalAttr;
unsigned long nLocalHeaderOffset;
};
struct ZipDirectoryEnd
{
unsigned short nThisDisk;
unsigned short nStartDisk;
unsigned short nDiskEntries;
unsigned short nTotalEntries;
unsigned long nSize;
unsigned long nStartOffset;
unsigned short nCommentLength;
};
#pragma pack()
class AgaZlibOutputStream : public wxZlibOutputStream
{
public:
AgaZlibOutputStream(wxOutputStream& stream, int level);
};
AgaZlibOutputStream::AgaZlibOutputStream(wxOutputStream& stream, int level)
: wxZlibOutputStream(stream, level)
{
const int DEF_MEM_LEVEL = 8;
deflateInit2_(m_deflate, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL,
Z_DEFAULT_STRATEGY, "1.1.2", sizeof(*m_deflate));
}
static int AddFilesToList(const wxString& strBase, const wxString& strMask, wxStringList& aFiles)
{
int n = 0;
wxString f = strBase + "/" + strMask;
f = ::wxFindFirstFile(f, 0);
while (!f.IsEmpty())
{
if (wxDirExists(f))
{
n += AddFilesToList(f, strMask, aFiles);
}
else
{
aFiles.Add(f);
n++;
}
f = ::wxFindNextFile();
}
return n;
}
static unsigned long ComputeCRC(const char* strFile)
{
const int nSize = 1024*64;
wxByte* buffer = new wxByte[nSize];
unsigned long dwCrc = 0;
wxFFileInputStream fin(strFile);
unsigned long nLastRead = nSize;
while (nLastRead == nSize)
{
fin.Read(buffer, nSize);
nLastRead= fin.LastRead();
dwCrc = crc32(dwCrc, buffer, nLastRead);
}
return dwCrc;
}
static void AddFileToZip(const wxString& strPrefix, const wxString& strFile,
wxFFileOutputStream& fout, wxFFileOutputStream& fdir)
{
if (!wxFileExists(strFile))
return;
wxString strPath, strName, strExt;
wxSplitPath(strFile, &strPath, &strName, &strExt);
wxString strRelName;
strRelName = strPath.Mid(strPrefix.Length());
if (!strRelName.IsEmpty())
strRelName += '/';
strRelName += strName;
strRelName += '.';
strRelName += strExt;
const off_t nStartPos = fout.TellO(); // Memorizzo posizione
const unsigned long dwLocalSignature = 0x04034B50;
fout.Write(&dwLocalSignature, sizeof(dwLocalSignature)); // Scrivo PK34
ZipLocalFileHeader zlfh; memset(&zlfh, 0, sizeof(zlfh));
zlfh.nVersionNeeded = 20; // You need at least pkunzip 2.0
zlfh.nFlags = 0x0002; // Deep Hacking ???
zlfh.nMethod = 8; // Implode
zlfh.nNameLength = strRelName.Length();
fout.Write(&zlfh, sizeof(zlfh)); // Scrivo header azzerato
fout.Write((const char*)strRelName, zlfh.nNameLength); // Scrivo nome file
const off_t nDataStart = fout.TellO(); // Memorizzo posizione dati compressi
const int nMagicOffset = -4; // Deep hacking :-)
{
wxFFileInputStream fin(strFile);
AgaZlibOutputStream zout(fout, 9);
zout.Write(fin); // Scrivo file compresso
zlfh.dwUncompressedSize = fin.TellI();
}
fout.SeekO(nMagicOffset, wxFromEnd);
zlfh.dwCompressedSize = fout.TellO();
zlfh.dwCompressedSize -= nDataStart;
zlfh.dwCRC = ComputeCRC(strFile);
const time_t tMod = ::wxFileModificationTime(strFile);
const struct tm* t = localtime(&tMod);
if (t != NULL)
{
zlfh.nLastModDate = t->tm_mday + ((t->tm_mon+1) << 5) + ((t->tm_year-80) << 9);
zlfh.nLastModTime = t->tm_sec/2 + (t->tm_min << 5) + (t->tm_hour << 11);
}
fout.SeekO(nStartPos+sizeof(dwLocalSignature), wxFromStart);
fout.Write(&zlfh, sizeof(zlfh));
// fout.Write((const char*)strRelName, strRelName.Length());
// Deep Hacking Here!
// const wxByte pkHeader = 0x85;
// fout.Write(&pkHeader, 1);
fout.SeekO(nMagicOffset, wxFromEnd);
ZipDirectoryFileHeader zdfh; memset(&zdfh, 0, sizeof(zdfh));
zdfh.nVersionUsed = zlfh.nVersionNeeded;
memcpy(&zdfh.zlfh, &zlfh, sizeof(zlfh));
zdfh.nLocalHeaderOffset = nStartPos;
const unsigned long dwDirectorySignature = 0x02014B50; // Scrivo PK12
fdir.Write(&dwDirectorySignature, sizeof(dwDirectorySignature));
fdir.Write(&zdfh, sizeof(zdfh)); // Scrivo entry directory
fdir.Write((const char*)strRelName, strRelName.Length());
}
static bool AddFilesToZip(const wxString& strBase, wxStringList& aFiles, const char* zipfile)
{
const char* zipdir = "zipdir.tmp";
wxFFileOutputStream fout(zipfile);
off_t nDirSize = 0, nDirStart = 0;
if (aFiles.GetCount() > 0) // Dummy test
{
wxFFileOutputStream fdir(zipdir);
wxStringListNode* node = aFiles.GetFirst();
while (node)
{
const wxString strFile = node->GetData();
AddFileToZip(strBase, strFile, fout, fdir);
node = node->GetNext();
}
nDirSize = fdir.TellO();
nDirStart = fout.TellO();
}
if (nDirSize > 0)
{
wxFFileInputStream fdir(zipdir);
fout.Write(fdir); // Append central directory
ZipDirectoryEnd zde; memset(&zde, 0, sizeof(zde));
zde.nDiskEntries = zde.nTotalEntries = aFiles.GetCount();
zde.nSize = nDirSize;
zde.nStartOffset = nDirStart;
const unsigned long dwEndDirectorySignature = 0x06054B50;
fout.Write(&dwEndDirectorySignature, sizeof(dwEndDirectorySignature));
fout.Write(&zde, sizeof(zde));
}
if (nDirSize > 0)
wxRemoveFile(zipdir);
return nDirSize > 0;
}
bool aga_zip(const char* srcfiles, const char* zipfile)
{
wxString strBase, strMask, strExt;
wxSplitPath(srcfiles, &strBase, &strMask, &strExt);
strMask += '.';
strMask += strExt;
wxStringList aFiles;
AddFilesToList(strBase, strMask, aFiles);
return AddFilesToZip(strBase, aFiles, zipfile);
}
bool aga_zip_filelist(const char* filelist, const char* zipfile)
{
wxStringList aFiles;
ifstream fin(filelist);
while (!fin.eof())
{
char name[MAX_PATH];
fin.getline(name, sizeof(name));
if (*name)
aFiles.Add(name);
else
break;
}
return AddFilesToZip("", aFiles, zipfile);
}