diff options
| author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2008-12-13 20:09:31 +0000 |
|---|---|---|
| committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2008-12-13 20:09:31 +0000 |
| commit | bc7917daeb494de9c17d2daf779c7cd612329e35 (patch) | |
| tree | 659bc54c9779050750db51e3d6b32d0b4db4475a | |
| parent | b42f379fa3f354ccc94266604bd30ac4f7ad70de (diff) | |
| download | rockbox-bc7917daeb494de9c17d2daf779c7cd612329e35.zip rockbox-bc7917daeb494de9c17d2daf779c7cd612329e35.tar.gz rockbox-bc7917daeb494de9c17d2daf779c7cd612329e35.tar.bz2 rockbox-bc7917daeb494de9c17d2daf779c7cd612329e35.tar.xz | |
Make Rockbox Utility error out if the zip file its going to install requires more space than left on the device. Calculation adds a safety space of 1MB so you need at least 1MB more free space than the extracted archive. This also catches differences due to the size calculation not taking cluster losses into account. Free disk space is also displayed in the sysinfo dialog. Fixes FS#9417.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19428 a1c6a512-1295-4272-9138-f99709370657
| -rw-r--r-- | rbutil/rbutilqt/base/rbunzip.cpp | 18 | ||||
| -rw-r--r-- | rbutil/rbutilqt/base/rbunzip.h | 9 | ||||
| -rw-r--r-- | rbutil/rbutilqt/base/utils.cpp | 42 | ||||
| -rw-r--r-- | rbutil/rbutilqt/base/utils.h | 1 | ||||
| -rw-r--r-- | rbutil/rbutilqt/installzip.cpp | 13 | ||||
| -rw-r--r-- | rbutil/rbutilqt/sysinfo.cpp | 29 |
6 files changed, 100 insertions, 12 deletions
diff --git a/rbutil/rbutilqt/base/rbunzip.cpp b/rbutil/rbutilqt/base/rbunzip.cpp index 49d1215..fb964b5 100644 --- a/rbutil/rbutilqt/base/rbunzip.cpp +++ b/rbutil/rbutilqt/base/rbunzip.cpp @@ -21,6 +21,7 @@ #include <QtCore> +//! @brief extract archive to destination UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest) { QStringList files = this->fileList(); @@ -41,8 +42,25 @@ UnZip::ErrorCode RbUnZip::extractArchive(const QString& dest) return error; } + +//! @brief abort an extractArchive() operation. void RbUnZip::abortUnzip(void) { m_abortunzip = true; } + +//! @brief return total size of extracted files in archive. +qulonglong RbUnZip::totalSize(void) +{ + QList<ZipEntry> l = this->entryList(); + qulonglong total = 0; + + int i = l.size(); + while(i--) + total += l.at(i).uncompressedSize; + + return total; + +} + diff --git a/rbutil/rbutilqt/base/rbunzip.h b/rbutil/rbutilqt/base/rbunzip.h index 133437a..c0b7215 100644 --- a/rbutil/rbutilqt/base/rbunzip.h +++ b/rbutil/rbutilqt/base/rbunzip.h @@ -28,12 +28,13 @@ class RbUnZip : public QObject, public UnZip { - Q_OBJECT - public: + Q_OBJECT + public: UnZip::ErrorCode extractArchive(const QString&); + qulonglong totalSize(void); - signals: - void unzipProgress(int, int); + signals: + void unzipProgress(int, int); public slots: void abortUnzip(void); diff --git a/rbutil/rbutilqt/base/utils.cpp b/rbutil/rbutilqt/base/utils.cpp index a6a80c6..64fc18e 100644 --- a/rbutil/rbutilqt/base/utils.cpp +++ b/rbutil/rbutilqt/base/utils.cpp @@ -32,6 +32,9 @@ #include <tchar.h> #include <winioctl.h> #endif +#if defined(Q_OS_LINUX) +#include <sys/statvfs.h> +#endif // recursive function to delete a dir with files bool recRmdir( const QString &dirName ) @@ -78,7 +81,7 @@ QString resolvePathCase(QString path) for(int i = start; i < elems.size(); i++) { QStringList direlems - = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System); + = QDir(realpath).entryList(QDir::AllEntries|QDir::Hidden|QDir::System); if(direlems.contains(elems.at(i), Qt::CaseInsensitive)) { // need to filter using QRegExp as QStringList::filter(QString) // matches any substring @@ -99,3 +102,40 @@ QString resolvePathCase(QString path) return realpath; } + +//! @brief figure the free disk space on a filesystem +//! @param path path on the filesystem to check +//! @return size in bytes +qulonglong filesystemFree(QString path) +{ + qlonglong size = 0; +#if defined(Q_OS_LINUX) + // the usage of statfs() is deprecated by the LSB so use statvfs(). + struct statvfs fs; + int ret; + + ret = statvfs(qPrintable(path), &fs); + + if(ret == 0) + size = fs.f_bsize * fs.f_bavail; +#endif +#if defined(Q_OS_MACX) + struct statfs fs; + int ret; + + ret = statfs(qPrintable(path), &fs); + + if(ret == 0) + size = fs.f_bsize * fs.f_bavail; +#endif +#if defined(Q_OS_WIN32) + BOOL ret; + ULARGE_INTEGER freeAvailBytes; + + ret = GetDiskFreeSpaceExW((LPCTSTR)path.utf16(), &freeAvailBytes, NULL, NULL); + if(ret) + size = freeAvailBytes.QuadPart; +#endif + return size; +} + diff --git a/rbutil/rbutilqt/base/utils.h b/rbutil/rbutilqt/base/utils.h index 19cdca9..0a91354 100644 --- a/rbutil/rbutilqt/base/utils.h +++ b/rbutil/rbutilqt/base/utils.h @@ -28,6 +28,7 @@ bool recRmdir( const QString &dirName ); QString resolvePathCase(QString path); +qulonglong filesystemFree(QString path); #endif diff --git a/rbutil/rbutilqt/installzip.cpp b/rbutil/rbutilqt/installzip.cpp index 5842e00..9539e3a 100644 --- a/rbutil/rbutilqt/installzip.cpp +++ b/rbutil/rbutilqt/installzip.cpp @@ -19,7 +19,7 @@ #include "installzip.h" #include "rbunzip.h" - +#include "utils.h" ZipInstaller::ZipInstaller(QObject* parent): QObject(parent) { @@ -148,6 +148,17 @@ void ZipInstaller::downloadDone(bool error) return; } + // check for free space. Make sure after installation will still be + // some room for operating (also includes calculation mistakes due to + // cluster sizes on the player). + if(filesystemFree(m_mountpoint) < (uz.totalSize() + 1000000)) { + m_dp->addItem(tr("Not enough disk space! Aborting."), LOGERROR); + m_dp->abort(); + m_dp->setProgressMax(1); + m_dp->setProgressValue(1); + emit done(true); + return; + } ec = uz.extractArchive(m_mountpoint); // TODO: better handling of aborted unzip operation. if(ec != UnZip::Ok) { diff --git a/rbutil/rbutilqt/sysinfo.cpp b/rbutil/rbutilqt/sysinfo.cpp index 7ca4b85..9a4c8b7 100644 --- a/rbutil/rbutilqt/sysinfo.cpp +++ b/rbutil/rbutilqt/sysinfo.cpp @@ -21,6 +21,8 @@ #include "sysinfo.h" #include "ui_sysinfofrm.h" #include "detect.h" +#include "utils.h" +#include "autodetection.h" Sysinfo::Sysinfo(QWidget *parent) : QDialog(parent) @@ -37,18 +39,33 @@ void Sysinfo::updateSysinfo(void) { QString info; info += tr("<b>OS</b><br/>") + Detect::osVersionString() + "<hr/>"; - info += tr("<b>Username:</b><br/>%1<hr/>").arg(Detect::userName()); + info += tr("<b>Username</b><br/>%1<hr/>").arg(Detect::userName()); #if defined(Q_OS_WIN32) - info += tr("<b>Permissions:</b><br/>%1<hr/>").arg(Detect::userPermissionsString()); + info += tr("<b>Permissions</b><br/>%1<hr/>").arg(Detect::userPermissionsString()); #endif - info += tr("<b>Attached USB devices:</b><br/>"); + info += tr("<b>Attached USB devices</b><br/>"); QMap<uint32_t, QString> usbids = Detect::listUsbDevices(); QList<uint32_t> usbkeys = usbids.keys(); - for(int i = 0; i < usbkeys.size(); i++) - info += tr("VID: %1 PID: %2, %3<br/>") + for(int i = 0; i < usbkeys.size(); i++) { + info += tr("VID: %1 PID: %2, %3") .arg((usbkeys.at(i)&0xffff0000)>>16, 4, 16, QChar('0')) .arg(usbkeys.at(i)&0xffff, 4, 16, QChar('0')) - .arg(usbids.value(usbkeys.at(i))); + .arg(usbids.value(usbkeys.at(i))); + if(i + 1 < usbkeys.size()) + info += "<br/>"; + } + info += "<hr/>"; + + info += "<b>" + tr("Filesystem") + "</b><br/>"; + QStringList drives = Autodetection::mountpoints(); + for(int i = 0; i < drives.size(); i++) { + info += tr("%1, %2 MiB available") + .arg(drives.at(i)) + .arg(filesystemFree(drives.at(i)) / (1024*1024)); + if(i + 1 < drives.size()) + info += "<br/>"; + } + info += "<hr/>"; ui.textBrowser->setHtml(info); } |