Newer shinier install log file which is more intelligent and better able to cope with multiple packages being installed. This breaks compatibility with the old uninstall file format.

Various bug fixes and tidy ups.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11757 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Christi Scarborough 2006-12-14 03:55:15 +00:00
parent 8f08f29a66
commit 5003669541
13 changed files with 385 additions and 83 deletions

View file

@ -7,11 +7,11 @@
# $Id$
#
# Unix-style Makefile for rbutil
# Unix-style Makefile for rbutil
CXX=$(shell $(PREFIX)wx-config --cxx)
OBJS=rbutil.o rbutilApp.o rbutilFrm.o wizard_pages.o
OBJS=rbutil.o rbutilApp.o rbutilFrm.o wizard_pages.o installog.o
# type "make WIN=1" for a Windows build using the Debian mingw cross-compiler

View file

@ -26,7 +26,7 @@
static char* rbutil_developers[] = {
"Christi Alice Scarborough",
""
"Dave Chapman"
};
//static char* rbutil_translators[] = (
@ -37,7 +37,7 @@ static char* rbutil_developers[] = {
#define RBUTIL_COPYRIGHT "(C) 2005-6 The Rockbox Team - " \
"released under the GNU Public License v2"
#define RBUTIL_DESCRIPTION "Utility for performing housekeepng tasks for" \
"the Rockbox audio jukebox firmware."
"the Rockbox open\nsource digital audio player firmware."
class AboutDlg: public wxDialog

153
rbutil/installlog.cpp Normal file
View file

@ -0,0 +1,153 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: installlog.cpp
*
* Copyright (C) 2006 Christi Alice Scarborough
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "installlog.h"
#include "rbutil.h"
InstallLog::InstallLog(wxString logname, bool CreateLog)
{
wxString buf;
dirtyflag = true;
if (! CreateLog && ! wxFileExists(logname) ) return;
logfile = new wxFileConfig(wxEmptyString, wxEmptyString, logname);
if (!logfile)
{
buf.Printf(_("Failed to create install log file: %s"), logname.c_str());
wxLogWarning(buf);
return;
}
logfile->SetPath("/InstallLog");
if (logfile->Exists("Version") &&
logfile->Read("Version", 0l) != LOGFILE_VERSION )
{
buf.Printf(_("Logfile version mismatch: %s"), logname.c_str() );
wxLogWarning(buf);
delete logfile;
return;
}
logfile->Write("Version", LOGFILE_VERSION);
dirtyflag = false;
}
InstallLog::~InstallLog()
{
if (dirtyflag) return;
delete logfile;
}
unsigned int InstallLog::WriteFile(wxString filepath, bool isDir)
{
wxString key, buf;
long installcount = 0;
if (dirtyflag) return true;
filepath.Replace(PATH_SEP, wxT("/") );
if (filepath.GetChar(0) == '/')
filepath = filepath.Right(filepath.Len() - 1);
logfile->SetPath(wxT("/FilePaths"));
installcount = logfile->Read(filepath, 0l);
if (isDir)
{
filepath.Append(wxT("/" DIRECTORY_KLUDGE) ); // Needed for empty dirs
}
logfile->Write(filepath, ++installcount);
return false;
}
unsigned int InstallLog::WriteFile(wxArrayString filepaths)
{
unsigned long i;
unsigned int finalrc = false;
wxString thisone;
if (dirtyflag) return true;
for (i = 0; i < filepaths.GetCount(); i++);
{
if ( WriteFile(filepaths[i]) )
{
finalrc++;
}
}
return finalrc;
}
wxArrayString* InstallLog::GetInstalledFiles()
{
wxString curdir = "";
if (dirtyflag) return NULL;
workingAS.Clear();
EnumerateCurDir("");
wxArrayString* out = new wxArrayString(workingAS);
return out;
}
void InstallLog::EnumerateCurDir(wxString curdir)
{
bool contflag;
wxString curname, buf, buf2, pathcache;
long dummy;
buf.Printf(wxT("/FilePaths/%s"), curdir.c_str());
pathcache = logfile->GetPath();
logfile->SetPath(buf);
contflag = logfile->GetFirstGroup(curname, dummy);
while (contflag)
{
buf.Printf("%s/%s", curdir.c_str(), curname.c_str() );
buf2 = buf; buf2.Replace(wxT("/"), wxT(PATH_SEP));
workingAS.Add(buf2);
EnumerateCurDir(buf);
contflag = logfile->GetNextGroup(curname, dummy);
}
contflag = logfile->GetFirstEntry(curname, dummy);
while (contflag)
{
if (curname != wxT(DIRECTORY_KLUDGE) )
{
buf.Printf("%s/%s", curdir.c_str(), curname.c_str() );
buf2 = buf; buf2.Replace(wxT("/"), wxT(PATH_SEP));
workingAS.Add(buf2);
}
contflag = logfile->GetNextEntry(curname, dummy);
}
logfile->SetPath(pathcache);
}

61
rbutil/installlog.h Normal file
View file

@ -0,0 +1,61 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: installlog.h
*
* Copyright (C) 2006 Christi Alice Scarborough
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef INSTALLLOG_H_INCLUDED
#define INSTALLLOG_H_INCLUDED
#include <wx/wxprec.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/confbase.h>
#include <wx/fileconf.h>
#define LOGFILE_VERSION 1
#define DIRECTORY_KLUDGE "_DIRECTORY_MARKER_RECORD_KLUDGE_"
class InstallLog
{
// Class variables
wxFileConfig* logfile;
// Methods
public:
InstallLog(wxString logname, bool CreateLog = true);
~InstallLog();
unsigned int WriteFile(wxString filepath, bool isDir = false);
unsigned int WriteFile(wxArrayString filepaths);
wxArrayString* GetInstalledFiles();
private:
bool dirtyflag;
wxArrayString workingAS;
// long dummy;
private:
void EnumerateCurDir(wxString curdir);
}; // InstallLog
#endif // INSTALLLOG_H_INCLUDED

View file

@ -1,8 +1,8 @@
#define RBUTIL 1
#include <wx/msw/wx.rc>
RBUTIL VERSIONINFO
FILEVERSION 0,2,0,0
PRODUCTVERSION 0,2,0,0
FILEVERSION 0,2,1,0
PRODUCTVERSION 0,2,1,0
FILEOS 0x00000004
FILETYPE 0x00000001
BEGIN
@ -10,12 +10,12 @@ BEGIN
BEGIN
BLOCK "FFFF0000"
BEGIN
VALUE "FileVersion", "0.2.0.0\0"
VALUE "ProductVersion", "0.2.0.0\0"
VALUE "FileVersion", "0.2.1.0\0"
VALUE "ProductVersion", "0.2.1.0\0"
VALUE "CompanyName", "Rockbox Team\0"
VALUE "FileDescription", "Rockbox Utility\0"
VALUE "InternalName", "rbutil\0"
VALUE "LegalCopyright", "(C) 2005,5 Rockbox Team\0"
VALUE "LegalCopyright", "(C) 2005,6 Rockbox Team\0"
VALUE "ProductName", "Rockbox Utility\0"
END
END

View file

@ -19,6 +19,7 @@
****************************************************************************/
#include "rbutil.h"
#include "installlog.h"
// This class allows us to return directories as well as files to
// wxDir::Traverse
@ -195,9 +196,11 @@ int DownloadURL(wxString src, wxString dest)
int UnzipFile(wxString src, wxString destdir, bool isInstall)
{
wxZipEntryPtr entry;
wxString in_str, progress_msg, buf, logfile = wxT("");
int errnum = 0, curfile = 0, totalfiles = 0;
wxZipEntryPtr entry;
wxString in_str, progress_msg, buf;
int errnum = 0, curfile = 0, totalfiles = 0;
InstallLog* log = NULL;
wxLogVerbose(_("===begin UnzipFile(%s,%s,%i)"),
src.c_str(), destdir.c_str(), isInstall);
@ -245,6 +248,13 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall)
wxPD_REMAINING_TIME | wxPD_CAN_ABORT);
progress->Update(0);
// We're not overly worried if the logging fails
if (isInstall)
{
buf.Printf(wxT("%s" PATH_SEP UNINSTALL_FILE), destdir.c_str());
log = new InstallLog(buf);
}
while (! errnum &&
(entry.reset(in_zip->GetNextEntry()), entry.get() != NULL) )
{
@ -260,15 +270,11 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall)
}
in_str.Printf(wxT("%s" PATH_SEP "%s"), destdir.c_str(), name.c_str());
buf = logfile;
// We leave space for adding a future CRC check, if we ever
// feel particularly enthunsiastic.
logfile.Printf(wxT("0 %s\n%s"), name.c_str(), buf.c_str());
if (entry->IsDir() ) {
wxDir* dirname = new wxDir(in_str);
if (! dirname->Exists(in_str) ) {
if (wxMkDir(in_str, 0777) ) {
if (! wxMkdir(in_str, 0777) ) {
buf.Printf(_("Unable to create directory %s"),
in_str.c_str() );
errnum = 100;
@ -276,6 +282,7 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall)
break;
}
}
log->WriteFile(name, true); // Directory
delete dirname;
continue;
}
@ -286,6 +293,9 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall)
buf.Printf(_("Can't open file %s for writing"), in_str.c_str() );
delete out;
return 100;
} else if (isInstall)
{
log->WriteFile(name);
}
in_zip->Read(*out);
@ -316,21 +326,9 @@ int UnzipFile(wxString src, wxString destdir, bool isInstall)
if (errnum)
{
ERR_DIALOG(buf, _("Unzip File"));
} else if (isInstall)
{
// If this fails, we have no log. No biggie.
buf = logfile;
logfile.Printf(wxT("%s " PATH_SEP "\n%s"), gv->curplat.c_str(),
buf.c_str());
buf.Printf(wxT("%s" PATH_SEP UNINSTALL_FILE),
destdir.c_str());
wxFFileOutputStream* out = new wxFFileOutputStream(buf);
out->Write(logfile, logfile.Len());
out->Close();
delete out;
}
if (log) delete log;
wxLogVerbose(_("=== end UnzipFile"));
return(errnum);
}
@ -340,6 +338,8 @@ int Uninstall(const wxString dir, bool isFullUninstall) {
bool gooddata = false;
unsigned int i;
bool errflag = false;
InstallLog *log = NULL;
wxArrayString* FilesToRemove = NULL;
wxLogVerbose(_("=== begin Uninstall(%s,%i)"), dir.c_str(), isFullUninstall);
@ -351,25 +351,13 @@ int Uninstall(const wxString dir, bool isFullUninstall) {
if (! isFullUninstall)
{
buf.Printf(wxT("%s" PATH_SEP UNINSTALL_FILE), dir.c_str());
if ( wxFileExists(buf) )
{
wxFFileInputStream* uninst_data = new wxFFileInputStream(buf);
if (uninst_data->Ok() )
{
wxStringOutputStream* out = new wxStringOutputStream(&uninst);
uninst_data->Read(*out);
if (uninst_data->GetLastError() == wxSTREAM_EOF &&
! out->GetLastError() )
{
gooddata = true;
}
delete out;
}
delete uninst_data;
}
if (! gooddata) {
buf.Printf(wxT("%s" PATH_SEP UNINSTALL_FILE), dir.c_str());
log = new InstallLog(buf, false); // Don't create the log
FilesToRemove = log->GetInstalledFiles();
if (log) delete log;
if (FilesToRemove == NULL || FilesToRemove->GetCount() < 1) {
wxLogNull lognull;
if ( wxMessageDialog(NULL,
_("Rockbox Utility can't find any uninstall data on this "
@ -439,25 +427,16 @@ int Uninstall(const wxString dir, bool isFullUninstall) {
{
wxString instplat, this_path_sep;
unsigned int totalfiles, rc;
totalfiles = FilesToRemove->GetCount();
FilesToRemove->Sort(true); // Reverse alphabetical ie dirs after files
// First line is "<platform><space><path seperator>\n"
instplat = uninst.BeforeFirst(wxT(' '));
this_path_sep = uninst.AfterFirst(wxT(' ')).BeforeFirst(wxT('\n'));
uninst = uninst.AfterFirst(wxT('\n'));
totalfiles = uninst.Freq(wxT('\n'));
i = 0;
while ((buf = uninst.BeforeFirst(wxT('\n'))) != "" )
for (i = 0; i < totalfiles; i++)
{
// These lines are all "<crc (unused)><space><filename>\n"
buf = buf.AfterFirst(wxT(' '));
buf = buf.Format(wxT("%s" PATH_SEP "%s"), dir.c_str(), buf.c_str());
// So we can install under Linux and still uninstall under Win
buf.Replace(this_path_sep, PATH_SEP);
wxString* buf2 = new wxString;
buf.Printf("%s%s", dir.c_str() , FilesToRemove->Item(i).c_str() );
buf2->Format(_("Deleting %s"), buf.c_str());
if (! progress->Update(++i * 100 / totalfiles, *buf2) )
if (! progress->Update((i + 1) * 100 / totalfiles, *buf2) )
{
WARN_DIALOG(_("Cancelled by user"), _("Normal Uninstall"));
delete progress;
@ -468,7 +447,7 @@ int Uninstall(const wxString dir, bool isFullUninstall) {
{
// If we're about to attempt to remove .rockbox. delete
// install data first
buf2->Printf(wxT("%s" PATH_SEP ".rockbox" PATH_SEP), dir.c_str() );
buf2->Printf(wxT("%s" PATH_SEP ".rockbox"), dir.c_str() );
if ( buf.IsSameAs(buf2->c_str()) )
{
buf2->Printf(wxT("%s" PATH_SEP UNINSTALL_FILE), dir.c_str());
@ -503,10 +482,12 @@ int Uninstall(const wxString dir, bool isFullUninstall) {
}
if (errflag)
{
ERR_DIALOG(_("Unable to remove some files"),
_("Standard uninstall")) ;
ERR_DIALOG(_("Unable to remove some files"),
_("Standard uninstall")) ;
}
}
if (FilesToRemove != NULL) delete FilesToRemove;
}
delete progress;
wxLogVerbose(_("=== end Uninstall"));
@ -541,21 +522,35 @@ wxString stream_err_str(int errnum)
bool InstallRbutil(wxString dest)
{
wxArrayString filestocopy;
wxString str, buf, dstr, destdir;
wxString str, buf, dstr, localpath, destdir;
unsigned int i;
wxDir dir;
bool copied_exe = false;
bool copied_exe = false, made_rbdir = false;
InstallLog* log;
buf.Printf(wxT("%s" PATH_SEP ".rockbox"), dest.c_str() );
if (! wxDirExists(buf) )
{
wxMkdir(buf);
made_rbdir = true;
}
buf.Printf(wxT("%s" PATH_SEP UNINSTALL_FILE), dest.c_str() );
log = new InstallLog(buf);
if (made_rbdir) log->WriteFile(wxT(".rockbox"), true);
destdir.Printf(wxT("%s" PATH_SEP "RockboxUtility"), dest.c_str());
if (! wxDirExists(destdir) )
{
if (! wxMkdir(destdir) )
if (! wxMkdir(destdir, 0777) )
{
buf.Printf(wxT("%s (%s)"),
_("Unable to create directory for installer"), destdir.c_str());
WARN_DIALOG(buf , _("Portable install") );
return false;
}
log->WriteFile(wxT("RockboxUtility"), true);
}
dir.GetAllFiles(gv->ResourceDir, &filestocopy, wxT("*"),
@ -583,6 +578,9 @@ bool InstallRbutil(wxString dest)
WARN_DIALOG(buf, _("Portable Install") );
return false;
}
buf = dstr;
buf.Replace(dest, wxEmptyString, false);
log->WriteFile(buf);
}
if (! copied_exe)
@ -597,6 +595,9 @@ bool InstallRbutil(wxString dest)
WARN_DIALOG(buf, _("Portable Install") );
return false;
}
buf = dstr;
buf.Replace(dest, wxEmptyString, false);
log->WriteFile(buf);
}
// Copy the local ini file so that it knows that it's a portable copy
@ -610,7 +611,11 @@ bool InstallRbutil(wxString dest)
WARN_DIALOG(buf, _("Portable Install") );
return false;
}
buf = dstr;
buf.Replace(dest, wxEmptyString, false);
log->WriteFile(buf);
delete log;
return true;
}

View file

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "Rockbox Utility"
#define MyAppVerName "Rockbox Utility v0.2"
#define MyAppVerName "Rockbox Utility v0.2.1"
#define MyAppPublisher "Rockbox Team"
#define MyAppURL "http://www.rockbox.org/"
#define MyAppExeName "rbutil.exe"
@ -17,8 +17,8 @@ AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={pf}\{#MyAppName}
DefaultGroupName={#MyAppName}
LicenseFile=C:\Documents and Settings\christi\My Documents\devel\rbutil\copying.txt
OutputBaseFilename=rbutil-0.2-setup
LicenseFile=copying.txt
OutputBaseFilename=rbutil-0.2.1-setup
Compression=lzma/ultra
SolidCompression=true
OutputDir=.

View file

@ -216,6 +216,7 @@ void rbutilFrmApp::ReadUserConfig()
gv->UserConfig = new wxFileConfig(wxEmptyString, wxEmptyString, buf);
gv->UserConfigFile = buf;
gv->UserConfig->Set(gv->UserConfig); // Store wxWidgets internal settings
stack = gv->UserConfig->GetPath();
gv->UserConfig->SetPath(wxT("/defaults"));

View file

@ -1,10 +1,22 @@
//---------------------------------------------------------------------------
//
// Name: rbutilApp.h
// Author: Christi Scarborough
// Created: 03/12/2005 00:35:02
//
//---------------------------------------------------------------------------
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: rbutilApp.h
*
* Copyright (C) 2005 Christi Alice Scarborough
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <wx/wxprec.h>
#ifdef __BORLANDC__

View file

@ -259,7 +259,7 @@ void rbutilFrm::OnFileWipeCache(wxCommandEvent& event)
MESG_DIALOG(_("Errors occured deleting the local download cache."));
}
wxMkDir(cacheloc, 0777);
wxMkdir(cacheloc, 0777);
}
@ -416,7 +416,16 @@ void rbutilFrm::OnFontBtn(wxCommandEvent& event)
if (wizard->RunWizard(page1) )
{
dest.Printf("%s" PATH_SEP "download" PATH_SEP "build-info",
buf.Printf(wxT("%s" PATH_SEP ".rockbox"), gv->curdestdir.c_str()) ;
if (! wxDirExists(buf) )
{
buf.Printf(_("Rockbox is not yet installed on %s - install "
"Rockbox first."), buf.c_str() );
WARN_DIALOG(buf, _("Can't install fonts") );
return;
}
dest.Printf(wxT("%s" PATH_SEP "download" PATH_SEP "build-info"),
gv->stdpaths->GetUserDataDir().c_str());
if (DownloadURL(gv->server_conf_url, dest))
{
@ -463,7 +472,7 @@ void rbutilFrm::OnFontBtn(wxCommandEvent& event)
}
}
if ( !UnzipFile(dest, gv->curdestdir) )
if ( !UnzipFile(dest, gv->curdestdir, true) )
{
MESG_DIALOG(_("The Rockbox fonts have been installed on your device.") );
} else

View file

@ -1,3 +1,23 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: wizardpages.cpp
*
* Copyright (C) 2005 Christi Alice Scarborough
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "wizard_pages.h"
wxPlatformPage::wxPlatformPage(wxWizard *parent) : wxWizardPageSimple(parent)

View file

@ -1,3 +1,24 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: wizard_pages.h
*
* Copyright (C) 2005 Christi Alice Scarborough
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __wizard_pages_HPP_
#define __wizard_pages_HPP_

View file

@ -1,3 +1,23 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* Module: rbutil
* File: wx_pch.h
*
* Copyright (C) 2005 wxWidgets team
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef WX_PCH_H_INCLUDED
#define WX_PCH_H_INCLUDED