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);
* 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<br>
- * otherwise: the full path of the target directory
+ * @param item the info about the backup item
+ * @param tempoararyMounted the device which was newly mounted.<br>
+ * "": device was already mounted
+ * @return "": not found<br>
+ * 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
* @param logger the logger
* @return <code>true</code>: 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;
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);
};
*/
#include "backupgui.hpp"
+#define WITH_TRACE
+#include "base/retrace.hpp"
+DECLARE_TRACER(s_traceConfig, "/tmp/bup_conf.log");
/**
* Constructor.
*/
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();
}
if (item.m_uid.isEmpty())
item.m_uid = QString(ReRandomizer::buildUUID());
}
+ FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp,
+ "<Configuration::check\n"));
}
/**
*/
void Configuration::load(QString filename)
{
+ 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");
fclose(fp);
}
check();
+ FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp,
+ "<Configuration::load: %s\n",
+ filename.toLocal8Bit().constData()));
}
/**
* @return <code>true</code>: the last backup date has been found (and
* set in <code>item</code>)
*/
-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());
}
}
}
+ m_mainWindow->unmount(temporaryMounted);
+ FILETRACE_IT(s_traceConfig, (s_traceConfig.m_fp,
+ "<Configuration::readBackupDate\n"));
return rc;
}
void check();
BackupItemList& items();
void load(QString filename);
- bool readBackupDate(BackupItem& item);
+ ReSuccess_t readBackupDate(BackupItem& item);
void save(QString filename);
private:
#include "backupgui.hpp"
#include "aboutdialog.hpp"
#include <QFileDialog>
+#define WITH_TRACE
+#include "base/retrace.hpp"
+DECLARE_TRACER(s_traceMain, "/tmp/bup_main.log");
const QString VERSION("2016.04.07");
m_maxListSize(100),
m_mutexLastFile(),
m_lastFile(""),
- m_lastDirectory("")
-
+ m_lastDirectory(""),
+ m_textChangeLocked(false),
+ m_temporaryMounted("")
{
initializeGui();
}
* @return <code>true</code>: success<br>
* 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;
return rc;
}
+/**
+ * Loads the mount and block device info.
+ */
+void MainWindow::loadOsInfo(){
+ ReMountInfo::instance(true);
+ ReBlockDevices::instance(true);
+}
+
/**
* Called at the program's end.
*/
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 {
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 {
* @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,
+ "<onDirPatternTextChanged:\n"));
}
/**
* @param newText the new text of the dir pattern
*/
void MainWindow::onFilePatternTextChanged(const QString& newText){
- UNUSED_VAR(newText);
- onUpdateConfig();
+ 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,
+ "<onFilePatternTextChanged:\n"));
}
/**
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 {
ui->actionClean->setEnabled(! isStart);
if (isStart)
BackupEngine::m_verboseLevel = (ReVerbose_t) ui->comboBoxVerbose->currentIndex();
- if (! isStart)
+ if (! isStart){
setStatusMessage(LOG_INFO, "");
+ unmount("");
+ }
}
* 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();
if (ui->checkBoxAutoSave->isChecked())
onSaveConfig();
}
+ FILETRACE_IT(s_traceMain, (s_traceMain.m_fp,
+ "<onUpdateConfig:\n"));
}
/**
*/
void MainWindow::updateTable(QTableWidget* target)
{
+ FILETRACE_IT(s_traceMain, (s_traceMain.m_fp,
+ ">updateTable:\n"));
if (target == NULL){
updateTable(ui->tableWidget);
updateTable(ui->tableWidgetConfiguration);
updateTableRow(ix, m_configuration.items()[ix], target);
}
}
+ FILETRACE_IT(s_traceMain, (s_traceMain.m_fp,
+ "<updateTable:\n"));
}
/**
onSaveConfig();
}
-
-
-
+/**
+ * Unmounts the current target device.
+ *
+ * @param device "": internal device is used.<br>
+ * 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)));
+ }
+}
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();
QMutex m_mutexLastFile;
QString m_lastFile;
QString m_lastDirectory;
+ bool m_textChangeLocked;
+ QString m_temporaryMounted;
};
#endif // MAINWINDOW_HPP
* @return true: OK<br>
* 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();
* @return true: OK<br>
* 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 {
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();
};
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.
* <code>false</code>: 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)) {
* @return <code>true</code>: success: the directory exists<br>
* <code>false</code>: 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) {
* @return <code>true</code>: success: the directory exists<br>
* <code>false</code>: 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);
}
/**
* @return <code>true</code>: success: the directory exists<br>
* <code>false</code>: 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 {
* @return <code>true</code>: success: the directory exists<br>
* <code>false</code>: 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);
}
* @param logger the logger
* @return <code>true</code>: 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,
* @param logger the logger
* @return <code>true</code>: 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
* @param logger the logger
* @return <code>true</code>: 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());
return rc;
}
- bool rc = true;
-
/** Sets the read position of a file.
* @param file file to process
* @param offset the position. @see <code>whence</code>
_unlink(rc.constData());
return rc;
}
-
-#if defined _WIN32
+#if 0
/**
* Converts the unix time (milliseconds from 1.1.1970) to the WIN32 filetime.
*
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<QString, QString>::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 <code>true</code>: 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 <code>NULL</code> or the error logger
+ * @return <code>true</code>: 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 <code>NULL</code>: not found
+ * otherwise: the block device with the given label
+ */
+const ReBlockDevice* ReBlockDevices::findByLabel(const QString& label) const
+{
+ const ReBlockDevice* rc = NULL;
+ QList<ReBlockDevice>::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 <code>NULL</code>: not found
+ * otherwise: the block device with the given label
+ */
+const ReBlockDevice* ReBlockDevices::findByDevice(const QString& device) const
+{
+ const ReBlockDevice* rc = NULL;
+ QList<ReBlockDevice>::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 <code>true</code>: 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
+
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);
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);
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);
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<QString, QString> m_deviceOfMountPoint;
+ QMap<QString, QString> 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<ReBlockDevice> m_devices;
+private:
+ static ReBlockDevices* m_instance;
+};
+
+#endif
+
#endif // REFILEUTILS_HPP
* @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++) {
* @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());
}
* @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());
}
* @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;
* @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);
// 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;
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 <code>NULL</code>
+ * @return <code>true</code>: 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.
*
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
* @param info OUT: the reserved area in the header
* @return <code>true</code>: 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;
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,
* @return true: successful<br>
* 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) {
* @return <code>true</code>: success<br>
* <code>false</code>: 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;
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<QByteArray> toArray(const char* source, const char* separator);
static QByteArray toCString(const char* source, int maxLength = -1);
#include <QMutex>
typedef unsigned char uint8_t;
+/** <code>true</code> 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
#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)
* @param type the type of the queue entry
* @param widget NULL or the target widget
* @param info the info for the target widget
- * @return <code>true</code>
+ * @return <code>true</code> (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));
* @return <code>true</code>: the info could be put into the widget<br>
* <code>false</code>: 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!
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;
/**
* Initializes the instance for writing the storage information.
+ *
+ * @return <code>true</code>: 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)
}
/**
* Initializes the instance for writing the storage information.
+ *
+ * @return <code>true</code>: 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) {
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
*/