From: hama Date: Sun, 15 May 2016 06:26:55 +0000 (+0200) Subject: rebackgui: integrated mount and blkid X-Git-Url: https://gitweb.hamatoma.de/?a=commitdiff_plain;h=a5f99baab8b75c75af5b9254ee85163a5e990e97;p=reqt rebackgui: integrated mount and blkid * no script is needed for mount and blkid info * refactoring: ReSuccess_t and ReTrue_t --- diff --git a/appl/rebackgui/BackupUtils.cpp b/appl/rebackgui/BackupUtils.cpp index 91891b4..2b7e5d4 100644 --- a/appl/rebackgui/BackupUtils.cpp +++ b/appl/rebackgui/BackupUtils.cpp @@ -44,18 +44,16 @@ QString BackupUtils::findAbstractTarget(const QString& path, ReLogger* logger) QString rc; #if defined __linux__ QStringList args; - args << "/usr/local/bin/osconnect.pl" - << "find-label" << path; - QByteArray output = ReProcess::executeAndRead("/usr/bin/perl", args, 20); - QByteArrayList lines = output.split('\n'); - if (lines.count() < 2){ - logger->log(LOG_ERROR, LOC_FIND_TARGET_1, "missing lines from osconnect.pl"); - } else if (lines.at(1).startsWith("+++")) { - logger->logv(LOG_ERROR, LOC_FIND_TARGET_2, "mounting failed: %s", - lines.at(1).mid(3).constData()); - } else { - rc = QString::fromUtf8(lines.at(0)) + ";" - + QString::fromUtf8(lines.at(1)); + ReMountInfo& mountInfo = ReMountInfo::instance(true); + QString device = mountInfo.findDevice(path); + if (! device.isEmpty()){ + ReBlockDevices& devices = ReBlockDevices::instance(true); + const ReBlockDevice* dev = devices.findByDevice(device); + if (dev != NULL){ + QString mountedAt = mountInfo.m_mountPointOfDevice.value(device); + QString relativePath = path.mid(mountedAt.length() + 1); + rc = "L=" + dev->m_label + ";" + relativePath; + } } #elif defined _WIN32 rc = ";" + path.mid(2); @@ -70,35 +68,46 @@ QString BackupUtils::findAbstractTarget(const QString& path, ReLogger* logger) * Note: if the medium of the target is an external medium * the path can change. * - * @param item the info about the backup item - * @return "": not found
- * otherwise: the full path of the target directory + * @param item the info about the backup item + * @param tempoararyMounted the device which was newly mounted.
+ * "": device was already mounted + * @return "": not found
+ * otherwise: the full path of the target directory */ -QString BackupUtils::findTarget(const BackupItem& item, ReLogger* logger) +QString BackupUtils::findTarget(const BackupItem& item, MainWindow& mainWindow, + QString& tempoararyMounted) { QString rc; #if defined __linux__ + tempoararyMounted.clear(); if (item.m_target.isEmpty()){ // nothing to do } else if (item.m_target.startsWith(";/")){ // the path is an absolute path on a fixed disk: rc = item.m_target.mid(1); } else { + ReBlockDevices& devices = ReBlockDevices::instance(); QStringList parts = item.m_target.split(';'); QStringList args; - args << "/usr/local/bin/osconnect.pl" - << "search-target" << parts.at(0) - << parts.at(1) - << "/media/EFI_system/backup"; - QByteArray output = ReProcess::executeAndRead("/usr/bin/perl", args, 20); - QByteArrayList lines = output.split('\n'); - if (lines.count() < 2){ - logger->log(LOG_ERROR, LOC_FIND_TARGET_1, "missing lines from osconnect.pl"); - } else if (lines.at(1).startsWith("+++")) { - logger->logv(LOG_ERROR, LOC_FIND_TARGET_2, "mounting failed: %s", - lines.at(1).mid(3).constData()); - } else { - rc = QString::fromUtf8(lines.at(0)); + QString label = parts.at(0); + QString relativePath = parts.at(1); + if (label.startsWith("L=")) + label = label.mid(2); + const ReBlockDevice* device = devices.findByLabel(label); + if (device != NULL){ + ReMountInfo& mountInfo = ReMountInfo::instance(); + if (mountInfo.m_mountPointOfDevice.contains(device->m_device)){ + rc = mountInfo.m_mountPointOfDevice.value(device->m_device); + + OS_SEPARATOR + relativePath; + } else { + QStringList args; + QString mountPath = "/media/" + label; + ReFileUtils::makeDir(mountPath, mainWindow.logger()); + + if (ReMountInfo::mount(device->m_device, mountPath, &mainWindow)){ + tempoararyMounted = device->m_device; + } + } } } #elif defined _WIN32 @@ -151,7 +160,7 @@ QString BackupUtils::nameOfTargetDescription(const QString& path){ * @param logger the logger * @return true: target is already initialized */ -bool BackupUtils::prepareTarget(const QString& path, BackupItem &item, +ReSuccess_t BackupUtils::prepareTarget(const QString& path, BackupItem &item, ReLogger* logger) { bool rc = false; diff --git a/appl/rebackgui/BackupUtils.hpp b/appl/rebackgui/BackupUtils.hpp index 1f97ee1..7a8ab0a 100644 --- a/appl/rebackgui/BackupUtils.hpp +++ b/appl/rebackgui/BackupUtils.hpp @@ -19,9 +19,10 @@ public: public: static QString dateToString(const QDateTime& dateTime); static QString findAbstractTarget(const QString& path, ReLogger* logger); - static QString findTarget(const BackupItem& item, ReLogger* logger); + static QString findTarget(const BackupItem& item, MainWindow& mainWindow, + QString& temporaryMounted); static QString nameOfTargetDescription(const QString &path); - static bool prepareTarget(const QString &path, BackupItem &item, ReLogger *logger); + static ReSuccess_t prepareTarget(const QString &path, BackupItem &item, ReLogger *logger); static QDateTime stringToDate(const QString& dateTime); static QString targetDescription(const QString& backupPath, ReLogger *logger); }; diff --git a/appl/rebackgui/Configuration.cpp b/appl/rebackgui/Configuration.cpp index d461e49..88298e1 100644 --- a/appl/rebackgui/Configuration.cpp +++ b/appl/rebackgui/Configuration.cpp @@ -10,6 +10,9 @@ */ #include "backupgui.hpp" +#define WITH_TRACE +#include "base/retrace.hpp" +DECLARE_TRACER(s_traceConfig, "/tmp/bup_conf.log"); /** * Constructor. @@ -75,6 +78,8 @@ void Configuration::appendNew() */ void Configuration::check() { + FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp, + ">Configuration::check: size: %d\n", m_items.size())); if (m_items.size() == 0){ appendNew(); } @@ -83,6 +88,8 @@ void Configuration::check() if (item.m_uid.isEmpty()) item.m_uid = QString(ReRandomizer::buildUUID()); } + FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp, + "Configuration::load: %s\n", + filename.toLocal8Bit().constData())); if (filename.isEmpty()) filename = m_mainWindow->fileOfHome(m_mainWindow->applicationName() + ".conf"); FILE* fp = fopen(I18N::s2b(filename).constData(), "r"); @@ -164,6 +174,9 @@ void Configuration::load(QString filename) fclose(fp); } check(); + FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp, + "true: the last backup date has been found (and * set in item) */ -bool Configuration::readBackupDate(BackupItem& item){ - bool rc = false; - QString target = BackupUtils::findTarget(item, m_mainWindow->logger()); +ReSuccess_t Configuration::readBackupDate(BackupItem& item){ + FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp, + ">Configuration::readBackupDate: %s\n", + item.m_name.toLocal8Bit().constData())); + ReSuccess_t rc = false; + QString temporaryMounted; + QString target = BackupUtils::findTarget(item, *m_mainWindow, temporaryMounted); if (! target.isEmpty()){ QString name = BackupUtils::nameOfTargetDescription(target); ReConfig config(I18N::s2b(name).constData()); @@ -188,6 +205,9 @@ bool Configuration::readBackupDate(BackupItem& item){ } } } + m_mainWindow->unmount(temporaryMounted); + FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp, + " +#define WITH_TRACE +#include "base/retrace.hpp" +DECLARE_TRACER(s_traceMain, "/tmp/bup_main.log"); const QString VERSION("2016.04.07"); @@ -40,8 +43,9 @@ MainWindow::MainWindow(QApplication& application, const QString& homeDir, m_maxListSize(100), m_mutexLastFile(), m_lastFile(""), - m_lastDirectory("") - + m_lastDirectory(""), + m_textChangeLocked(false), + m_temporaryMounted("") { initializeGui(); } @@ -274,9 +278,9 @@ void MainWindow::initializeGui(){ * @return true: success
* otherwise: error occurred */ -bool MainWindow::initializeStart(){ +ReSuccess_t MainWindow::initializeStart(){ setStatusMessage(LOG_INFO, QObject::tr("Search started...")); - bool rc = true; + ReSuccess_t rc = true; BackupEngine::m_shouldStop = false; BackupEngine::m_searchReady = false; BackupEngine::m_hotBytes = 0; @@ -302,6 +306,14 @@ bool MainWindow::initializeStart(){ return rc; } +/** + * Loads the mount and block device info. + */ +void MainWindow::loadOsInfo(){ + ReMountInfo::instance(true); + ReBlockDevices::instance(true); +} + /** * Called at the program's end. */ @@ -396,7 +408,9 @@ void MainWindow::onChecksums(){ say(LOG_ERROR, tr("no backup item selected")); } else { BackupItem& item = m_configuration.items()[row]; - QString target = BackupUtils::findTarget(item, &m_logger); + loadOsInfo(); + QString target = BackupUtils::findTarget(item, *this, + m_temporaryMounted); if (target.isEmpty()){ say(LOG_ERROR, tr("Target not available")); } else { @@ -431,7 +445,8 @@ void MainWindow::onClean() say(LOG_ERROR, tr("no backup item selected")); } else { BackupItem& item = m_configuration.items()[row]; - QString target = BackupUtils::findTarget(item, &m_logger); + loadOsInfo(); + QString target = BackupUtils::findTarget(item, *this, m_temporaryMounted); if (target.isEmpty()){ say(LOG_ERROR, tr("Target not available")); } else { @@ -523,8 +538,16 @@ void MainWindow::onDeleteSource() * @param newText the new text of the dir pattern */ void MainWindow::onDirPatternTextChanged(const QString& newText){ - UNUSED_VAR(newText); - onUpdateConfig(); + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + ">onDirPatternTextChanged:\n")); + if (! m_textChangeLocked){ + m_textChangeLocked = true; + UNUSED_VAR(newText); + onUpdateConfig(); + m_textChangeLocked = false; + } + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + "onFilePatternTextChanged:\n")); + if (! m_textChangeLocked){ + m_textChangeLocked = true; + UNUSED_VAR(newText); + onUpdateConfig(); + } + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + "actionClean->setEnabled(! isStart); if (isStart) BackupEngine::m_verboseLevel = (ReVerbose_t) ui->comboBoxVerbose->currentIndex(); - if (! isStart) + if (! isStart){ setStatusMessage(LOG_INFO, ""); + unmount(""); + } } @@ -756,6 +789,8 @@ void MainWindow::startStop(bool isStart){ * Stores the GUI elements into the current backup item and save int to the file. */ void MainWindow::onUpdateConfig(){ + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + ">onUpdateConfig:\n")); if (m_guiIsInitialized){ BackupItem& item = m_configuration.items()[m_currentRowConfiguration]; item.m_name = ui->lineEditName->text(); @@ -770,6 +805,8 @@ void MainWindow::onUpdateConfig(){ if (ui->checkBoxAutoSave->isChecked()) onSaveConfig(); } + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + "updateTable:\n")); if (target == NULL){ updateTable(ui->tableWidget); updateTable(ui->tableWidgetConfiguration); @@ -855,6 +894,8 @@ void MainWindow::updateTable(QTableWidget* target) updateTableRow(ix, m_configuration.items()[ix], target); } } + FILETRACE_IT(s_traceMain, (s_traceMain.m_fp, + " + * otherwise: the device to unmount + */ +void MainWindow::unmount(const QString& device) +{ + const QString& device2 = device.isEmpty() ? m_temporaryMounted : device; + if (! device2.isEmpty()){ + QStringList args; + args << device2; + QByteArray answer = ReProcess::executeAndRead("/bin/umount", args); + + if (answer.isEmpty()) + externalLog(tr("device %1 successfully unmounted") + .arg(device2)); + else + externalError(tr("cannot unmount device %1: %2") + .arg(device2) + .arg(QString::fromUtf8(answer))); + } +} diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp index 1f63750..366c3e9 100644 --- a/appl/rebackgui/mainwindow.hpp +++ b/appl/rebackgui/mainwindow.hpp @@ -38,11 +38,13 @@ public: void setLastFile(const QString& lastFile); void setLastFile(const QString& lastDir, const QString& lastFile); void saveState(); + void unmount(const QString& device); protected slots: private: void extractTarget(const QString& dir); void initializeGui(); bool initializeStart(); + void loadOsInfo(); void writeTargetConfiguration(BackupItem& item, const QString& target); private slots: void onAbout(); @@ -94,6 +96,8 @@ private: QMutex m_mutexLastFile; QString m_lastFile; QString m_lastDirectory; + bool m_textChangeLocked; + QString m_temporaryMounted; }; #endif // MAINWINDOW_HPP diff --git a/base/ReConfig.cpp b/base/ReConfig.cpp index b95be38..d4d7be6 100644 --- a/base/ReConfig.cpp +++ b/base/ReConfig.cpp @@ -194,8 +194,8 @@ void ReConfig::put(const char *key, const char *value) * @return true: OK
* false: error occurred */ -bool ReConfig::read(const char* file) { - bool rc = true; +ReSuccess_t ReConfig::read(const char* file) { + ReSuccess_t rc = true; m_lineList.reserve(1024); if (file == NULL) file = m_file.constData(); @@ -235,8 +235,8 @@ bool ReConfig::read(const char* file) { * @return true: OK
* false: error occurred */ -bool ReConfig::write(const char* file) { - bool rc = false; +ReSuccess_t ReConfig::write(const char* file) { + ReSuccess_t rc = false; if (m_readOnly) m_logger->log(LOG_ERROR, LOC_WRITE_1, "cannot write: (readonly"); else { diff --git a/base/ReConfig.hpp b/base/ReConfig.hpp index b2bdb44..14e61e9 100644 --- a/base/ReConfig.hpp +++ b/base/ReConfig.hpp @@ -27,8 +27,8 @@ public: void put(const char* key, bool value); void put(const char* key, int value); void put(const char* key, const char* value); - bool read(const char* file = NULL); - bool write(const char* file = NULL); + ReSuccess_t read(const char* file = NULL); + ReSuccess_t write(const char* file = NULL); private: void initLogger(); diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index f52fe2c..4a86676 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -23,8 +23,9 @@ enum { }; int ReFileUtils::m_maxCharSet = 128; bool ReFileUtils::m_ignoreSetUidError = false; - QDateTime ReFileUtils::m_undefinedTime; +ReMountInfo* ReMountInfo::m_instance = NULL; +ReBlockDevices* ReBlockDevices::m_instance = NULL; /** * Constructor. @@ -275,9 +276,9 @@ QString ReFileUtils::copy(const QString& source, const QString& target, * false: at least one deletion failed */ -bool ReFileUtils::deleteTree(const QString& path, bool withBase, +ReSuccess_t ReFileUtils::deleteTree(const QString& path, bool withBase, ReLogger* logger) { - bool rc = true; + ReSuccess_t rc = true; QDir dir(path); if (dir.exists(path)) { @@ -587,7 +588,7 @@ mode_t ReFileUtils::nativePermissions(QFile::Permissions permissions){ * @return true: success: the directory exists
* false: error occurred */ -bool ReFileUtils::makeDir(const char* path, ReLogger* logger) { +ReSuccess_t ReFileUtils::makeDir(const char* path, ReLogger* logger) { struct stat info; bool rc = true; if (stat(path, &info) != 0) { @@ -613,7 +614,7 @@ bool ReFileUtils::makeDir(const char* path, ReLogger* logger) { * @return true: success: the directory exists
* false: error occurred */ -bool ReFileUtils::makeDir(const QString& path, ReLogger* logger) { +ReSuccess_t ReFileUtils::makeDir(const QString& path, ReLogger* logger) { return makeDir(I18N::s2b(path).constData(), logger); } /** @@ -624,9 +625,9 @@ bool ReFileUtils::makeDir(const QString& path, ReLogger* logger) { * @return true: success: the directory exists
* false: error occurred */ -bool ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { +ReSuccess_t ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { struct stat info; - bool rc = false; + ReSuccess_t rc = false; if (stat(path, &info) == 0 && S_ISDIR(info.st_mode)){ rc = true; } else { @@ -673,7 +674,7 @@ bool ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { * @return true: success: the directory exists
* false: error occurred */ -bool ReFileUtils::makeDirWithParents(const QString& path, ReLogger* logger) { +ReSuccess_t ReFileUtils::makeDirWithParents(const QString& path, ReLogger* logger) { return makeDirWithParents(I18N::s2b(path).constData(), logger); } @@ -881,9 +882,9 @@ QByteArray ReFileUtils::replaceExtension(const char* path, const char* ext) { * @param logger the logger * @return true: success */ -bool ReFileUtils::setPermissions(const char* filename, +ReSuccess_t ReFileUtils::setPermissions(const char* filename, QFile::Permissions permissions, ReLogger* logger) { - bool rc = true; + ReSuccess_t rc = true; if (! QFile::setPermissions(QString(filename), permissions)){ if (logger != NULL) logger->logv(LOG_ERROR, LOC_SET_TIMES_1, @@ -903,9 +904,9 @@ bool ReFileUtils::setPermissions(const char* filename, * @param logger the logger * @return true: success */ -bool ReFileUtils::setTimes(const char* filename, const QDateTime& modified, +ReSuccess_t ReFileUtils::setTimes(const char* filename, const QDateTime& modified, const QDateTime& accessed, ReLogger* logger) { - bool rc = true; + ReSuccess_t rc = true; #if defined __linux__ struct timeval vals[2]; int64_t millisec = accessed == m_undefinedTime @@ -967,9 +968,9 @@ bool ReFileUtils::setTimes(const char* filename, const QDateTime& modified, * @param logger the logger * @return true: success */ - bool ReFileUtils::setTimes(const QString& filename, const QDateTime& modified, + ReSuccess_t ReFileUtils::setTimes(const QString& filename, const QDateTime& modified, const QDateTime& accessed, ReLogger* logger) { - bool rc = true; + ReSuccess_t rc = true; #if defined _WIN32 // utime does not work with VS10-32-bit FILETIME accessed2 = unixTimeToFileTime(accessed.toMSecsSinceEpoch()); @@ -996,8 +997,6 @@ bool ReFileUtils::setTimes(const char* filename, const QDateTime& modified, return rc; } - bool rc = true; - /** Sets the read position of a file. * @param file file to process * @param offset the position. @see whence @@ -1185,8 +1184,7 @@ QByteArray ReFileUtils::tempFile(const char* node, const char* parent, _unlink(rc.constData()); return rc; } - -#if defined _WIN32 +#if 0 /** * Converts the unix time (milliseconds from 1.1.1970) to the WIN32 filetime. * @@ -1223,3 +1221,201 @@ void ReFileUtils::writeToFile(const char* filename, const char* content, fclose(fp); } } +#ifdef __linux__ +/** + * Constructor. + */ +ReMountInfo::ReMountInfo() +{ + load(); +} +/** + * Reads the mount info with the command mount. + */ +void ReMountInfo::load() +{ + QStringList args; + QByteArray output = ReProcess::executeAndRead("/bin/mount", args, 20); + QByteArrayList lines = output.split('\n'); + QString device; + QRegularExpression regExpr("^(.*?) on (.*) type "); + QString relativePath; + QString line; + QString directory; + for (int ix = 0; ix < lines.size(); ix++){ + line = I18N::b2s(lines.at(ix)); + QRegularExpressionMatch match = regExpr.match(line); + if (match.hasMatch()){ + device = match.captured(1); + directory = match.captured(2); + m_deviceOfMountPoint.insert(directory, device); + m_mountPointOfDevice.insert(device, directory); + } + } +} + +/** + * Find the device of a given path. + * + * @param path the path + * @return the device with a mountpoint starting the path + */ +QString ReMountInfo::findDevice(const QString &path) +{ + QString rc; + QMap::const_iterator it; + for (it = m_deviceOfMountPoint.cbegin(); it != m_deviceOfMountPoint.cend(); ++it){ + QString path2 = *it; + if (path.startsWith(path2) && path2 != OS_SEPARATOR_STR) + rc = m_deviceOfMountPoint.value(path2); + } + return rc; +} +#endif + +#ifdef __linux__ +/** + * Returns a singleton instance. + * + * @forceLoad true: the current data will be loaded unconditional + * @return the singleton instance + */ +ReMountInfo& ReMountInfo::instance(bool forceLoad){ + if (m_instance == NULL) + m_instance = new ReMountInfo(); + else if (forceLoad) + m_instance->load(); + + return *m_instance; +} + +/** + * Mounts a block device to a given directory. + * + * @param device name of the device, e.g. "/dev/sdb1" + * @param path mount point (directory) + * @param announcer NULL or the error logger + * @return true: success + */ +ReSuccess_t ReMountInfo::mount(const QString& device, const QString& path, + ReAnnouncer* announcer) +{ + QStringList args; + args << "/bin/mount" << device << path; + QByteArray error; + ReSuccess_t rc = ReProcess::executeSilent("/usr/bin/sudo", args, 30, &error); + if (! rc &&& announcer != NULL) + announcer->say(LOG_ERROR, QString(error)); + return rc; +} +#endif + +#if 0 +bool equals(const QString& s1, const QString& s2){ + bool rc = s1.length() == s2.length(); + if (rc){ + for (int ix = 0; ix < s1.length(); ix++){ + if (s1.at(ix) != s2.at(ix)){ + rc = false; + break; + } + } + } + return rc; +} +#endif + +#ifdef __linux__ +/** + * Finds the block device by a given label. + * + * @param label label to search + * @return NULL: not found + * otherwise: the block device with the given label + */ +const ReBlockDevice* ReBlockDevices::findByLabel(const QString& label) const +{ + const ReBlockDevice* rc = NULL; + QList::const_iterator it; + for (it = m_devices.cbegin(); it != m_devices.cend(); ++it){ + if ((*it).m_label == label){ + rc = &*it; + break; + } + } + return rc; +} + +/** + * Finds the block device by a given label. + * + * @param label label to search + * @return NULL: not found + * otherwise: the block device with the given label + */ +const ReBlockDevice* ReBlockDevices::findByDevice(const QString& device) const +{ + const ReBlockDevice* rc = NULL; + QList::const_iterator it; + for (it = m_devices.cbegin(); it != m_devices.cend(); ++it){ + if ((*it).m_device == device){ + rc = &*it; + break; + } + } + return rc; +} +#endif + +#ifdef __linux__ +/** + * Constructor. + */ +ReBlockDevices::ReBlockDevices() +{ + load(); +} + +/** + * Returns the singleton instance. + * + * @forceLoad true: the current data will be always reloaded + * @return the singleton instance + */ +ReBlockDevices& ReBlockDevices::instance(bool forceLoad) +{ + if (m_instance == NULL) + m_instance = new ReBlockDevices(); + else if (forceLoad) + m_instance->load(); + return *m_instance; +} + +/** +* Reads the information from the blkid command. +*/ +void ReBlockDevices::load(){ + QStringList args; + QByteArray output = ReProcess::executeAndRead("/sbin/blkid", args, 20); + QByteArrayList lines = output.split('\n'); + QRegularExpression regExpr2("^([^:]+):.*?" + "( LABEL=\"([^\"]+)\")?" + " UUID=\"([^\"]+)\"" + " TYPE=\"([^\"]+)\""); + QString line; + for (int ix = 0; ix < lines.size(); ix++){ + line = I18N::b2s(lines.at(ix)); + QRegularExpressionMatch match = regExpr2.match(line); + if (match.hasMatch()){ + ReBlockDevice dev; + dev.m_device = match.captured(1); + dev.m_label = match.captured(3); + dev.m_uuid = match.captured(4); + dev.m_type = match.captured(5); + m_devices.append(dev); + } + } +} + +#endif + diff --git a/base/ReFileUtils.hpp b/base/ReFileUtils.hpp index 94dc5ea..3ffb5aa 100644 --- a/base/ReFileUtils.hpp +++ b/base/ReFileUtils.hpp @@ -49,7 +49,7 @@ public: static QString copy(const QString& source, const QString& target, const QFileInfo* sourceInfo, QByteArray& buffer, bool setUser = true); - static bool deleteTree(const QString& path, bool withBase, + static ReSuccess_t deleteTree(const QString& path, bool withBase, ReLogger* logger = NULL); static QString extensionOf(const QString& filename); static QByteArray extensionOf(const char* filename); @@ -86,10 +86,10 @@ public: return path.replace(OS_2nd_SEPARATOR, OS_SEPARATOR); #endif } - static bool makeDir(const char* path, ReLogger* logger = NULL); - static bool makeDir(const QString& path, ReLogger* logger = NULL); - static bool makeDirWithParents(const char* path, ReLogger* logger = NULL); - static bool makeDirWithParents(const QString& path, ReLogger* logger = NULL); + static ReSuccess_t makeDir(const char* path, ReLogger* logger = NULL); + static ReSuccess_t makeDir(const QString& path, ReLogger* logger = NULL); + static ReSuccess_t makeDirWithParents(const char* path, ReLogger* logger = NULL); + static ReSuccess_t makeDirWithParents(const QString& path, ReLogger* logger = NULL); static QString nodeOf(const QString& filename); static QByteArray nodeOf(const char* filename); static QString parentOf(const QString& filename); @@ -100,12 +100,12 @@ public: static QString replaceExtension(const QString& path, const QString& ext); static QByteArray replaceExtension(const char* path, const char* ext); static int seek(FILE* file, int64_t offset, int whence); - static bool setPermissions(const char* filename, + static ReSuccess_t setPermissions(const char* filename, QFile::Permissions permissions, ReLogger* logger = NULL); - static bool setTimes(const char* filename, const QDateTime& modified, + static ReSuccess_t setTimes(const char* filename, const QDateTime& modified, const QDateTime& accessed = m_undefinedTime, ReLogger* logger = NULL); - static bool setTimes(const QString& filename, const QDateTime& modified, + static ReSuccess_t setTimes(const QString& filename, const QDateTime& modified, const QDateTime& accessed = m_undefinedTime, ReLogger* logger = NULL); static void splitUrl(const QString& url, QString* protocol, QString* host, QString* path, QString* node, QString* params = NULL); @@ -128,4 +128,58 @@ public: static bool m_ignoreSetUidError; }; +#ifdef __linux__ +/** + * Holds the info shown by the "mount" command. + */ +class ReMountInfo { +public: + ReMountInfo(); +public: + void load(); + QString findDevice(const QString& path); +public: + QMap m_deviceOfMountPoint; + QMap m_mountPointOfDevice; +private: + static ReMountInfo* m_instance; +public: + static ReMountInfo& instance(bool forceLoad = false); + static ReSuccess_t mount(const QString& device, const QString& path, + ReAnnouncer* announcer = NULL); +}; + +/** + * Describes one device with the info get from the command "blkid". + */ +class ReBlockDevice { +public: + QString m_device; + QString m_label; + QString m_uuid; + QString m_type; + QString m_partitonUUID; +}; + +/** + * Holds the info shown by the "blkid" command. + */ +class ReBlockDevices { +public: + ReBlockDevices(); +public: + void load(); + const ReBlockDevice* findByLabel(const QString& label) const; + const ReBlockDevice* findByDevice(const QString& device) const; +public: + static ReBlockDevices& instance(bool forceLoad = false); + +private: + QList m_devices; +private: + static ReBlockDevices* m_instance; +}; + +#endif + #endif // REFILEUTILS_HPP diff --git a/base/ReLogger.cpp b/base/ReLogger.cpp index 2147d6a..544f304 100644 --- a/base/ReLogger.cpp +++ b/base/ReLogger.cpp @@ -265,7 +265,7 @@ const QByteArray& ReLogger::getStdPrefix(ReLoggerLevel level, int location) { * @param message the logging message * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, const char* message) { +ReTrue_t ReLogger::log(ReLoggerLevel level, int location, const char* message) { m_stdPrefix = ""; bool first = true; for (size_t ix = 0; ix < m_countAppenders; ix++) { @@ -288,7 +288,7 @@ bool ReLogger::log(ReLoggerLevel level, int location, const char* message) { * @param message the logging message * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, +ReTrue_t ReLogger::log(ReLoggerLevel level, int location, const QByteArray& message) { return log(level, location, message.data()); } @@ -301,7 +301,7 @@ bool ReLogger::log(ReLoggerLevel level, int location, * @param message the logging message * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, const ReString& message) { +ReTrue_t ReLogger::log(ReLoggerLevel level, int location, const ReString& message) { return log(level, location, I18N::s2b(message).data()); } @@ -314,7 +314,7 @@ bool ReLogger::log(ReLoggerLevel level, int location, const ReString& message) { * @param ... the values of the placeholders (varargs) * @return true: for chaining */ -bool ReLogger::logv(ReLoggerLevel level, int location, const char* format, +ReTrue_t ReLogger::logv(ReLoggerLevel level, int location, const char* format, ...) { char buffer[64000]; va_list ap; @@ -334,7 +334,7 @@ bool ReLogger::logv(ReLoggerLevel level, int location, const char* format, * @param varlist variable arguments * @return true: for chaining */ -bool ReLogger::log(ReLoggerLevel level, int location, const char* format, +ReTrue_t ReLogger::log(ReLoggerLevel level, int location, const char* format, va_list& varlist) { char buffer[64000]; qvsnprintf(buffer, sizeof buffer, format, varlist); diff --git a/base/ReLogger.hpp b/base/ReLogger.hpp index f3cc752..dc06f1d 100644 --- a/base/ReLogger.hpp +++ b/base/ReLogger.hpp @@ -88,11 +88,11 @@ private: // Prohibits assignment operator: no implementation! ReLogger& operator =(const ReLogger& source); public: - bool log(ReLoggerLevel level, int location, const char* message); - bool log(ReLoggerLevel level, int location, const QByteArray& message); - bool log(ReLoggerLevel level, int location, const ReString& message); - bool logv(ReLoggerLevel level, int location, const char* format, ...); - bool log(ReLoggerLevel level, int location, const char* format, + ReTrue_t log(ReLoggerLevel level, int location, const char* message); + ReTrue_t log(ReLoggerLevel level, int location, const QByteArray& message); + ReTrue_t log(ReLoggerLevel level, int location, const ReString& message); + ReTrue_t logv(ReLoggerLevel level, int location, const char* format, ...); + ReTrue_t log(ReLoggerLevel level, int location, const char* format, va_list& varlist); void addAppender(ReAppender* appender); ReAppender* findAppender(const char* name) const; diff --git a/base/ReProcess.cpp b/base/ReProcess.cpp index 2fdd856..e22cb79 100644 --- a/base/ReProcess.cpp +++ b/base/ReProcess.cpp @@ -43,6 +43,39 @@ QByteArray ReProcess::executeAndRead(const QString& program, return rc; } +/** + * Executes an external program which have normally no output. + * + * If an output is found this is an error message. + * + * @param program the program to execute + * @param args the program arguments + * @param timeout the maximal count of seconds waiting for program's end + * @param errorMessage OUT: error message. May be NULL + * @return true: success + */ +ReSuccess_t ReProcess::executeSilent(const QString& program, + const QStringList& args, int timeout, QByteArray* errorMessage) +{ + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + process.start(program, args, QIODevice::ReadOnly); + process.waitForFinished(timeout * 1000); + QByteArray output = process.readAllStandardOutput(); + bool rc = output.isEmpty(); + if (! rc){ + if (errorMessage != NULL) + *errorMessage = output; + } else { + QString error = process.errorString(); + rc = error.isEmpty(); + if (! rc && errorMessage != NULL){ + *errorMessage = output; + } + } + return rc; +} + /** * Executes an external program and return its output. * diff --git a/base/ReProcess.hpp b/base/ReProcess.hpp index c1c34dd..c932a48 100644 --- a/base/ReProcess.hpp +++ b/base/ReProcess.hpp @@ -21,10 +21,11 @@ public: public: static QByteArray executeAndRead(const QString& program, - const QStringList& args, int timeout = 60, bool mergeStdError = true); + const QStringList& args, int timeout = 60, bool mergeStdError = true); static QByteArray executeAndRead(const QByteArray& command, int timeout = 60); static QByteArray executeAndFilter(const char* command, const QString& regExpr); - + static bool executeSilent(const QString& program, const QStringList& args, + int timeout, QByteArray* errorMessage = NULL); }; #endif // REPROCESS_HPP diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index a2ad003..4e95a2e 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -1188,14 +1188,14 @@ ReRandomizer& ReByteScrambler::contentRandom(bool doReset) * @param info OUT: the reserved area in the header * @return true: success */ -bool ReByteScrambler::initFromHeader(int reservedLength, int markerLength, +ReSuccess_t ReByteScrambler::initFromHeader(int reservedLength, int markerLength, int infoLength, int encryptedFrom, QByteArray* header, QByteArray& info) { TRACE("initFromHeader():\n"); encryptedFrom = max(encryptedFrom, (int) sizeof(int64_t) + reservedLength + markerLength); - bool rc = true; + ReSuccess_t rc = true; if (header == NULL) header = &m_header; int headerLength = sizeof(int64_t) + reservedLength + markerLength + infoLength; diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index 21cbdc6..9fdce66 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -354,7 +354,7 @@ public: ReByteScrambler& operator =(const ReByteScrambler& source); public: ReRandomizer& contentRandom(bool doReset); - bool initFromHeader(int reservedLength, int markerLength, + ReSuccess_t initFromHeader(int reservedLength, int markerLength, int infoLength, int encryptedFrom, QByteArray* header, QByteArray& info); void initHeader(int reservedLength, int markerLength, int infoLength, diff --git a/base/ReStringUtils.cpp b/base/ReStringUtils.cpp index d8b450e..79a815d 100644 --- a/base/ReStringUtils.cpp +++ b/base/ReStringUtils.cpp @@ -434,7 +434,7 @@ QByteArray ReStringUtils::toNumber(int value, const char* format) { * @return true: successful
* false: error occurred */ -bool ReStringUtils::write(const char* file, const char* content, +ReSuccess_t ReStringUtils::write(const char* file, const char* content, const char* mode) { FILE* fp = fopen(file, mode); if (fp != NULL) { @@ -763,10 +763,10 @@ void ReCharSet::getMinMax(const char* charSet, char& minChar, char& maxChar) * @return true: success
* false: minChar or maxChar invalid or wrong size */ -bool ReCharSet::fillIndexOf(const char* charSet, char minChar, char maxChar, +ReSuccess_t ReCharSet::fillIndexOf(const char* charSet, char minChar, char maxChar, int* indexOf, size_t sizeIndexOf) { - bool rc = true; + ReSuccess_t rc = true; int length = maxChar - minChar + 1; if (length != int(sizeIndexOf / sizeof*indexOf)) rc = false; diff --git a/base/ReStringUtils.hpp b/base/ReStringUtils.hpp index c83eb69..007da6d 100644 --- a/base/ReStringUtils.hpp +++ b/base/ReStringUtils.hpp @@ -62,7 +62,7 @@ public: char separator = AUTO_SEPARATOR); static QByteArray read(const char* file, bool removeLastNewline = true); static QByteArray replaceNode(const char* source, const char* newNode); - static bool write(const char* file, const char* content = NULL, + static ReSuccess_t write(const char* file, const char* content = NULL, const char* mode = "w"); static QList toArray(const char* source, const char* separator); static QByteArray toCString(const char* source, int maxLength = -1); diff --git a/base/rebase.hpp b/base/rebase.hpp index 60dfb22..986fa58 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -56,6 +56,13 @@ #include typedef unsigned char uint8_t; +/** true means success. */ +typedef bool ReSuccess_t; +/** Always true */ +typedef bool ReTrue_t; +/** Always false */ +typedef bool ReFalse_t; + #if !defined __linux__ typedef qint64 int64_t; #endif diff --git a/base/retrace.hpp b/base/retrace.hpp index 21f7d91..e631b20 100644 --- a/base/retrace.hpp +++ b/base/retrace.hpp @@ -21,7 +21,8 @@ #define IF_TRACE(statem) statem #define DECLARE_TRACER(varName, fileName) static ReTracer varName(fileName) // Example: FILETRACE_IT(s_tracerLoop, (s_tracerLoop.m_fp, "value: %d", 33)); -#define FILETRACE_IT(varName, args) do { fprintf args; fflush(varName.m_fp); } while(false) +#define FILETRACE_IT(varName, args) do { if (varName.m_fp != NULL) { \ + fprintf args; fflush(varName.m_fp); } } while(false) #else #define TRACE(m) #define TRACE1(format, a1) diff --git a/gui/ReGuiApplication.cpp b/gui/ReGuiApplication.cpp index a2340c8..74d8326 100644 --- a/gui/ReGuiApplication.cpp +++ b/gui/ReGuiApplication.cpp @@ -153,9 +153,9 @@ ReLogger* ReGuiApplication::logger() * @param type the type of the queue entry * @param widget NULL or the target widget * @param info the info for the target widget - * @return true + * @return true (for chaining) */ -bool ReGuiApplication::externalAppend(ReGuiQueueItem::WidgetType type, QWidget* widget, +ReTrue_t ReGuiApplication::externalAppend(ReGuiQueueItem::WidgetType type, QWidget* widget, const QString& info){ m_mutexGuiQueue.lock(); m_guiQueue.pushBack(ReGuiQueueItem(type, widget, info)); diff --git a/gui/ReGuiQueue.cpp b/gui/ReGuiQueue.cpp index a9de75e..cb3ab29 100644 --- a/gui/ReGuiQueue.cpp +++ b/gui/ReGuiQueue.cpp @@ -82,9 +82,9 @@ ReGuiQueueItem ReGuiQueue::popFront() * @return true: the info could be put into the widget
* false: nothing is done */ -bool ReGuiQueueItem::apply(ReGuiQueue &queue, int maxItems) const +ReSuccess_t ReGuiQueueItem::apply(ReGuiQueue &queue, int maxItems) const { - bool rc = m_widget != NULL; + ReSuccess_t rc = m_widget != NULL; if (rc){ if (maxItems > 0 && queue.m_countOfType[m_type] > maxItems){ // nothing to do! diff --git a/gui/ReGuiQueue.hpp b/gui/ReGuiQueue.hpp index a5c0c7c..e0a91fa 100644 --- a/gui/ReGuiQueue.hpp +++ b/gui/ReGuiQueue.hpp @@ -62,7 +62,7 @@ public: return *this; } public: - bool apply(ReGuiQueue &queue, int maxItems = 0) const; + ReSuccess_t apply(ReGuiQueue &queue, int maxItems = 0) const; public: WidgetType m_type; QWidget* m_widget; diff --git a/gui/ReStateStorage.cpp b/gui/ReStateStorage.cpp index 879c144..8304183 100644 --- a/gui/ReStateStorage.cpp +++ b/gui/ReStateStorage.cpp @@ -150,8 +150,10 @@ QByteArray ReStateStorage::fullname(const char* name) { /** * Initializes the instance for writing the storage information. + * + * @return true: success */ -bool ReStateStorage::initForRead() { +ReSuccess_t ReStateStorage::initForRead() { if (m_fp == NULL) if ((m_fp = fopen(I18N::s2b(m_filename).constData(), "rb")) == NULL) { if (m_logger != NULL) @@ -178,8 +180,10 @@ bool ReStateStorage::initForRead() { } /** * Initializes the instance for writing the storage information. + * + * @return true: success */ -bool ReStateStorage::initForWrite() { +ReSuccess_t ReStateStorage::initForWrite() { if (m_fp == NULL) m_fp = fopen(I18N::s2b(m_filename).constData(), "wb"); if (m_fp == NULL) { diff --git a/gui/ReStateStorage.hpp b/gui/ReStateStorage.hpp index b44de8b..cfe9447 100644 --- a/gui/ReStateStorage.hpp +++ b/gui/ReStateStorage.hpp @@ -29,8 +29,8 @@ public: QByteArray fullname(const char* name); QStringList& historyAsList(const char* key, QStringList& list, const char* form = NULL); - bool initForRead(); - bool initForWrite(); + ReSuccess_t initForRead(); + ReSuccess_t initForWrite(); /** Returns the map containing the storage content. * @return the map */