2
* This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3
* http://www.gnu.org/licenses/gpl-3.0.html
6
* $Id: devpakinstaller.cpp 7109 2011-04-15 11:53:16Z mortenmacfly $
7
* $HeadURL: http://svn.code.sf.net/p/codeblocks/code/branches/release-16.xx/src/plugins/contrib/devpak_plugin/devpakinstaller.cpp $
10
#include "devpakinstaller.h"
14
#include "cbiniparser.h"
15
#include <wx/filename.h>
16
#include <wx/msgdlg.h>
18
DevPakInstaller::DevPakInstaller()
24
DevPakInstaller::~DevPakInstaller()
30
void DevPakInstaller::CreateProgressDialog(int max)
33
m_pDlg = new wxProgressDialog(_("Progress"), _T(""), max, 0, wxPD_APP_MODAL);
34
m_pDlg->SetSize(480, m_pDlg->GetSize().y);
38
void DevPakInstaller::EndProgressDialog()
45
void DevPakInstaller::UpdateProgress(int val, const wxString& newtext)
49
m_pDlg->Update(val, newtext);
54
bool DevPakInstaller::Install(const wxString& name, const wxString& filename, const wxString& dir, wxArrayString* files)
56
CreateProgressDialog(4);
60
UpdateProgress(0, _("Decompressing ") + filename);
63
wxString tmpfile = wxFileName::CreateTempFileName(_T("cb"));
64
if (!Decompress(filename, tmpfile))
66
m_Status += _(" [Decompression failed]");
67
wxRemoveFile(tmpfile);
72
// Step 2: un-tar .DevPackage file
73
UpdateProgress(1, _("Unpacking control-file"));
75
TAR* t = new TAR(tmpfile.c_str());
76
TAR::Record* r = t->FindFile(_T("*.DevPackage"));
77
wxString controlFile = r->name;
79
if (!r || !t->ExtractFile(r, dir, status2))
81
m_Status << _(" [Control file unpacking failed] - ");
84
wxRemoveFile(tmpfile);
90
UpdateProgress(2, _("Unpacking all files"));
92
if (!Untar(controlFile, tmpfile, dir, files))
94
m_Status += _(" [Unpacking failed]");
96
wxRemoveFile(tmpfile);
97
RemoveControlFile(dir + _T("/") + controlFile);
102
UpdateProgress(3, _("Done"));
104
wxRemoveFile(tmpfile);
105
RemoveControlFile(dir + _T("/") + controlFile);
110
bool DevPakInstaller::Uninstall(const wxString& entry)
113
IniParser* p = new IniParser;
116
int idx = p->FindGroupByName(_T("Files"), false);
119
m_Status << _("No [Files] section in ") << entry << _T('\n');
122
wxArrayString pathlist;
123
CreateProgressDialog(p->GetKeysCount(idx));
124
for (int i = 0; i < p->GetKeysCount(idx); ++i)
126
wxString file = p->GetKeyName(idx, i);
127
UpdateProgress(i, _("Removing: ") + file);
128
if (!wxRemoveFile(file))
129
m_Status << _("Can't remove ") << file << _T('\n');
132
wxString path = wxPathOnly(file);
133
while (path.Last() == _T('/') || path.Last() == _T('\\'))
135
if (pathlist.Index(path) == wxNOT_FOUND)
141
CreateProgressDialog(pathlist.GetCount());
142
for (unsigned int i = 0; i < pathlist.GetCount(); ++i)
144
wxString path = pathlist[i];
145
int pos = path.Find(_T('/'), true);
146
while (pos != wxNOT_FOUND)
149
path.Remove(pos, path.Length() - pos);
150
UpdateProgress(i, _("Removing directory: ") + path);
151
pos = path.Find(_T('/'), true);
156
if (!wxRemoveFile(entry))
157
m_Status << _("Can't remove ") << entry << _T('\n');
159
return true; //m_Status.IsEmpty();
162
void DevPakInstaller::RemoveControlFile(const wxString& filename)
164
if (filename.IsEmpty())
166
wxRemoveFile(filename);
167
wxRmdir(wxFileName(filename).GetPath()); // deletes it if non-empty
170
bool DevPakInstaller::Decompress(const wxString& filename, const wxString& tmpfile)
173
FILE* f = fopen(filename.mb_str(), "rb");
176
m_Status = _("Error opening input file!");
182
BZFILE* bz = BZ2_bzReadOpen(&bzerror, f, 0, 0, 0L, 0);
183
if (!bz || bzerror != BZ_OK)
185
m_Status = _("Can't read compressed stream!");
191
FILE* fo = fopen(tmpfile.mb_str(), "wb");
194
m_Status = _("Error opening output file!");
199
// read stream writing to uncompressed file
201
while (bzerror != BZ_STREAM_END)
203
int read_bytes = BZ2_bzRead(&bzerror, bz, buffer, 2048);
204
if (bzerror != BZ_OK && bzerror != BZ_STREAM_END)
206
m_Status = _("Error reading from stream!");
207
BZ2_bzReadClose(&bzerror, bz);
212
fwrite(buffer, read_bytes, 1, fo);
215
BZ2_bzReadClose(&bzerror, bz);
223
bool DevPakInstaller::Untar(const wxString& controlFile, const wxString& filename, const wxString& dirname, wxArrayString* files)
225
TAR t(filename.c_str());
226
wxString tmpControlFile;
228
if (!controlFile.IsEmpty())
231
ini.ParseFile(dirname + _T("/") + controlFile);
232
int grp = ini.FindGroupByName(_T("Files"));
233
for (int i = 0; grp != -1 && i < ini.GetKeysCount(grp); ++i)
235
t.AddReplacer(ini.GetKeyName(grp, i), ini.GetKeyValue(grp, i));
238
// add replacers for all paths above controlFile
239
// i.e. in Allegro.DevPak:
240
// Test/Allegro.DevPackage (everything is below Test/),
241
// add replacer for Test/
242
int pos = controlFile.Last('/');
243
if (pos != wxNOT_FOUND)
245
wxString replacer = controlFile.SubString(0, pos);
246
tmpControlFile = controlFile;
247
tmpControlFile.Replace(replacer, _T(""));
248
t.AddReplacer(replacer, _T(""));
251
// add replacers (with user's permission) for DLLs
253
TAR::Record* r = t.FindFile(_T("*.dll"));
255
r = t.FindFile(_T("*.DLL"));
258
if (wxMessageBox(_("This package contains some DLLs.\nDo you want to install them system-wide (YES recommended)?"), _("Confirmation"), wxICON_QUESTION | wxYES_NO) == wxYES)
260
wxFileName fname(wxGetOSDirectory() + _T("/system32/"));
261
fname.MakeRelativeTo(dirname);
262
t.AddReplacer(_T("dll/"), fname.GetFullPath());
269
bool ret = t.ExtractAll(dirname.c_str(), m_Status, files);
270
if (!tmpControlFile.IsEmpty())
271
RemoveControlFile(dirname + _T("/") + tmpControlFile);