From bd907562dcc0e815e3306f910d5517502142a3d9 Mon Sep 17 00:00:00 2001 From: Hamatoma Date: Wed, 27 Jan 2016 23:48:36 +0100 Subject: [PATCH] rebackgui: works basicly under windows --- appl/rebackgui/BackupEngine.cpp | 22 ++++- appl/rebackgui/BackupUtils.cpp | 117 ++++++++++++++++++++++ appl/rebackgui/BackupUtils.hpp | 24 +++++ appl/rebackgui/Configuration.cpp | 26 +++-- appl/rebackgui/Configuration.hpp | 1 + appl/rebackgui/backupgui.hpp | 1 + appl/rebackgui/mainwindow.cpp | 91 ++++++++--------- appl/rebackgui/mainwindow.hpp | 5 +- appl/rebackgui/rebackgui.pro | 97 ++++++++++--------- base/ReConfig.cpp | 70 +++++++++++++- base/ReConfig.hpp | 20 ++-- base/ReFile.cpp | 8 +- base/ReFileUtils.cpp | 161 ++++++++++++++++++++++--------- base/ReFileUtils.hpp | 2 + base/ReQStringUtils.cpp | 6 +- base/ReRandomizer.cpp | 24 ++++- base/ReRandomizer.hpp | 1 + base/ReStringUtils.cpp | 68 +++++++++++++ base/ReStringUtils.hpp | 8 +- base/ReTest.cpp | 10 +- base/rebase.hpp | 10 +- cunit/cuReFileSystem.cpp | 6 +- cunit/cuReFileUtils.cpp | 8 +- cunit/cuReProcess.cpp | 7 ++ gui/ReGuiApplication.cpp | 2 +- os/ReFileSystem.cpp | 3 + os/ReFileSystem.hpp | 2 - os/reos.hpp | 5 +- 28 files changed, 614 insertions(+), 191 deletions(-) create mode 100644 appl/rebackgui/BackupUtils.cpp create mode 100644 appl/rebackgui/BackupUtils.hpp diff --git a/appl/rebackgui/BackupEngine.cpp b/appl/rebackgui/BackupEngine.cpp index 4fee13e..3950da9 100644 --- a/appl/rebackgui/BackupEngine.cpp +++ b/appl/rebackgui/BackupEngine.cpp @@ -227,8 +227,26 @@ BackupTask::BackupTask(const QString& name, */ void BackupTask::copyFile(int index, const QString& relPath, const QString& node){ QString source = m_sourceDirs.at(index) + relPath + node; - QString target = m_targetDirs.at(index) + relPath + node; - m_mainWindow->addToFileList(source + " -> " + target); + QString targetDir = m_targetDirs.at(index) + relPath; + QString target = targetDir + node; + ReQStringUtils::chomp(targetDir, OS_SEPARATOR); + bool isFile; + if (! ReFileUtils::isDirectory(targetDir, &isFile)){ + if (isFile){ + if (unlink(I18N::s2b(targetDir).constData()) != 0) + error(tr("cannot remove file (for making a directory (%1): %2") + .arg(errno).arg(targetDir)); + } + if (! ReFileUtils::makeDirWithParents(targetDir)) + error(tr("cannot make directory (%1): %2").arg(errno).arg(targetDir)); + } + QFile src(source); + unlink(I18N::s2b(target).constData()); + if (! src.copy(target)){ + error(tr("copy failed (%1): %2").arg(errno).arg(source)); + } else { + m_mainWindow->addToFileList(source); + } } /** diff --git a/appl/rebackgui/BackupUtils.cpp b/appl/rebackgui/BackupUtils.cpp new file mode 100644 index 0000000..ee777f6 --- /dev/null +++ b/appl/rebackgui/BackupUtils.cpp @@ -0,0 +1,117 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ +#include "backupgui.hpp" + +BackupUtils::BackupUtils() +{ + +} +/** + * Converts a date time to a string. + * + * @param dateTime the timepoint to convert + * @return the string representation + */ +QString BackupUtils::dateToString(const QDateTime &dateTime) +{ + QString rc = dateTime.toString("yyyy.MM.dd/hh:mm:ss"); + return rc; +} + +/** + * Finds the real path of a target directory. + * + * 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 + */ +QString BackupUtils::findTarget(const BackupItem& item, ReLogger* logger) +{ + QString rc; +#if defined __linux__ +#elif defined _WIN32 + QStringList drives = ReFileUtils::findRootDirs(); + QStringList::const_iterator it; + for (it = drives.cbegin(); it != drives.cend(); ++it){ + QString path = *it; + ReQStringUtils::ensureLastChar(path, OS_SEPARATOR); + int pos = item.m_target.indexOf(';'); + if (pos >= 0) + path += item.m_target.mid(pos + 1); + else + path += item.m_target; + QString markerFile = nameOfTargetDescription(path); + if (QFileInfo(markerFile).exists()){ + if (rc.isEmpty()) + rc = ReFileUtils::parentOf(markerFile); + ReConfig config(I18N::s2b(markerFile), true, logger); + if (! config.asString((item.m_uid + ".created").toLatin1(), + "").isEmpty()){ + rc = ReFileUtils::parentOf(markerFile); + break; + } + } + } +#endif + return rc; +} + +/** + * Returns the name of the file marking a backup target. + * + * @param path the path of the file + * @return the full name of the file + */ +QString BackupUtils::nameOfTargetDescription(const QString& path){ + QString fname = path; + ReQStringUtils::ensureLastChar(fname, OS_SEPARATOR); + fname += ".rebackgui.target"; + return fname; +} + +/** + * Prepares the target base directory. + * + * Creates a file. The program uses this file to recognize a target directory. + * + * @param path the target base directory + * @param item the info about the backup item + * @param logger the logger + * @return true: target is already initialized + */ +bool BackupUtils::prepareTarget(const QString& path, BackupItem &item, + ReLogger* logger) +{ + bool rc = false; + QString fname = nameOfTargetDescription(path); + ReConfig config(I18N::s2b(fname), false, logger); + QByteArray key = item.m_uid.toLatin1() + ".created"; + if (config.asString(key.constData(), "").isEmpty()){ + config.put(key, dateToString(QDateTime::currentDateTime()).toLatin1().constData()); + rc = true; + } + return rc; +} + +/** + * Converts a string into a date time. + * + * @param dateTime the string convert + * @return the date time + */ +QDateTime BackupUtils::stringToDate(const QString &dateTime) +{ + QDateTime rc; + rc.fromString(dateTime, "yyyy.MM.dd/hh:mm:ss"); + return rc; +} + + diff --git a/appl/rebackgui/BackupUtils.hpp b/appl/rebackgui/BackupUtils.hpp new file mode 100644 index 0000000..af97bfc --- /dev/null +++ b/appl/rebackgui/BackupUtils.hpp @@ -0,0 +1,24 @@ +/* + * Licence: + * You can use and modify this file without any restriction. + * There is no warranty. + * You also can use the licence from http://www.wtfpl.net/. + * The original sources can be found on https://github.com/republib. +*/ +#ifndef BACKUPUTILS_H +#define BACKUPUTILS_H + + +class BackupUtils +{ +public: + BackupUtils(); +public: + static QString dateToString(const QDateTime& dateTime); + static QString findTarget(const BackupItem& item, ReLogger* logger); + static QString nameOfTargetDescription(const QString &path); + static bool prepareTarget(const QString &path, BackupItem &item, ReLogger *logger); + static QDateTime stringToDate(const QString& dateTime); +}; + +#endif // BACKUPUTILS_H diff --git a/appl/rebackgui/Configuration.cpp b/appl/rebackgui/Configuration.cpp index dc5d241..0a0b884 100644 --- a/appl/rebackgui/Configuration.cpp +++ b/appl/rebackgui/Configuration.cpp @@ -13,6 +13,7 @@ */ BackupItem::BackupItem() : m_no(0), + m_uid(), m_name(), m_sources(), m_target(), @@ -26,6 +27,7 @@ BackupItem::BackupItem() : */ BackupItem::BackupItem(int no) : m_no(no), + m_uid(), m_name(), m_sources(), m_target(), @@ -59,6 +61,7 @@ void Configuration::appendNew() { BackupItem item(m_items.size()); item.m_name = QObject::tr("item") + QString::number(item.m_no + 1); + item.m_uid = QString(ReRandomizer::buildUUID()); m_items.append(item); } @@ -70,6 +73,11 @@ void Configuration::check() if (m_items.size() == 0){ appendNew(); } + for (int ix =0; ix < m_items.size(); ix++){ + BackupItem& item = m_items[ix]; + if (item.m_uid.isEmpty()) + item.m_uid = QString(ReRandomizer::buildUUID()); + } } /** @@ -122,9 +130,11 @@ void Configuration::load(QString filename) getItem(no, map).m_name = value; } else if (ReQStringUtils::hasPrefixAndNumber("sources", line2, no, value)){ getItem(no, map).m_sources = value.split(';'); - } else if (ReQStringUtils::hasPrefixAndNumber("target", line2, no, value)){ - getItem(no, map).m_target = value; - } else if (ReQStringUtils::hasPrefixAndNumber("filepatterns", line2, no, value)){ + } else if (ReQStringUtils::hasPrefixAndNumber("uid", line2, no, value)){ + getItem(no, map).m_uid = value; + } else if (ReQStringUtils::hasPrefixAndNumber("target", line2, no, value)){ + getItem(no, map).m_target = value; + } else if (ReQStringUtils::hasPrefixAndNumber("filepatterns", line2, no, value)){ getItem(no, map).m_filePatterns = value; } else if (ReQStringUtils::hasPrefixAndNumber("dirpatterns", line2, no, value)){ getItem(no, map).m_dirPatterns = value; @@ -167,9 +177,11 @@ void Configuration::save(QString filename) QByteArray buffer; for (int ix = 0; ix < m_items.size(); ix++){ BackupItem& item = m_items[ix]; - buffer = "name." + QByteArray::number(ix) + "=" - + item.m_name.toUtf8() + "\n"; - buffer += "sources." + QByteArray::number(ix) + "=" + buffer = "name." + QByteArray::number(ix) + "=" + + item.m_name.toUtf8() + "\n"; + buffer += "uid." + QByteArray::number(ix) + "=" + + item.m_uid.toUtf8() + "\n"; + buffer += "sources." + QByteArray::number(ix) + "=" + item.m_sources.join(';').toUtf8() + "\n"; buffer += "target." + QByteArray::number(ix) + "=" + item.m_target.toUtf8() + "\n"; @@ -178,7 +190,7 @@ void Configuration::save(QString filename) buffer += "dirpatterns." + QByteArray::number(ix) + "=" + item.m_dirPatterns.toUtf8() + "\n"; buffer += "lastbackup." + QByteArray::number(ix) + "=" - + item.m_lastBackup.toString("yyyy.MM.dd/hh:mm") + "\n"; + + BackupUtils::dateToString(item.m_lastBackup) + "\n"; if (fputs(buffer.constData(), fp) != buffer.length()) m_mainWindow->error(QObject::tr("cannot write (%1): %2").arg(errno) .arg(filename)); diff --git a/appl/rebackgui/Configuration.hpp b/appl/rebackgui/Configuration.hpp index 7ea2986..38df7ca 100644 --- a/appl/rebackgui/Configuration.hpp +++ b/appl/rebackgui/Configuration.hpp @@ -17,6 +17,7 @@ public: BackupItem(int no); public: int m_no; + QString m_uid; QString m_name; QStringList m_sources; QString m_target; diff --git a/appl/rebackgui/backupgui.hpp b/appl/rebackgui/backupgui.hpp index ea5db17..c2922fa 100644 --- a/appl/rebackgui/backupgui.hpp +++ b/appl/rebackgui/backupgui.hpp @@ -12,6 +12,7 @@ #include "gui/regui.hpp" #include "Configuration.hpp" #include "BackupEngine.hpp" +#include "BackupUtils.hpp" #include "mainwindow.hpp" #include "ui_mainwindow.h" diff --git a/appl/rebackgui/mainwindow.cpp b/appl/rebackgui/mainwindow.cpp index 95419d3..26b06a9 100644 --- a/appl/rebackgui/mainwindow.cpp +++ b/appl/rebackgui/mainwindow.cpp @@ -49,7 +49,6 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : SLOT(onLoadConfig())); connect(ui->actionSaveConfig, SIGNAL(triggered()), this, SLOT(onSaveConfig())); - connect(ui->pushButtonDeleteItem, SIGNAL(clicked()), this, SLOT(onNewDeleteItem())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(onAbout())); connect(ui->tableWidgetConfiguration->selectionModel(), SIGNAL( selectionChanged(const QItemSelection&, const QItemSelection&)), @@ -62,6 +61,7 @@ MainWindow::MainWindow(const QString& homeDir, QWidget *parent) : connect(ui->pushButtonClearErrorList, SIGNAL(clicked()), this, SLOT(onClearErrorList())); connect(ui->pushButtonClear, SIGNAL(clicked()), this, SLOT(onClearLog())); m_configuration.load(""); + ui->tableWidgetConfiguration->selectRow(0); updateTable(); updateItem(0); } @@ -106,6 +106,28 @@ bool MainWindow::error(const QString& message){ } +/** + * Find the target identification. + * + * @param dir the directory on the external medium (already mounted) + * @return the relative path + */ +QString MainWindow::extractTarget(const QString& dir){ + QString rc; + QString target; +#if defined __linux__ +#elif defined _WIN32 + rc = dir; + if (dir.length() >= 2 && dir.at(1) == ':') + rc.remove(0, 2); + if (rc.startsWith(OS_SEPARATOR_STR)) + rc.remove(0, 1); + target = ";" + rc; +#endif + ui->lineEditTarget->setText(target); + return rc; +} + /** * Set GUI elements from the queue when the GUI timer is triggered. */ @@ -263,23 +285,13 @@ void MainWindow::onSelectTarget(){ QFileDialog::ShowDirsOnly); if (!dir.isEmpty()){ dir = ReFileUtils::nativePath(dir); - findTarget(dir); + extractTarget(dir); + BackupItem& item = m_configuration.items()[m_currentRowConfiguration]; + if (! BackupUtils::prepareTarget(dir, item, &m_logger)) + say(LOG_INFO, tr("target initialized with %1") + .arg(BackupUtils::nameOfTargetDescription(dir))); } } - -/** - * Find the target identification. - * - * @param dir the directory on the external medium (already mounted) - */ -void MainWindow::findTarget(const QString& dir){ - QString target = ";" + dir; -#if defined __linux__ -#else -#endif - ui->lineEditTarget->setText(target); -} - /** * The current row has been changed. * @@ -307,19 +319,6 @@ void MainWindow::onSaveConfig(){ m_configuration.save(""); } -/** - * Builds the target directory. - * - * @return the target directory - */ -QString MainWindow::buildTargetDir(const QString& target){ - QString rc = target; - int ix = rc.indexOf(';'); - if (ix == 0) - rc.remove(0, 1); - return rc; -} - /** * Starts the backup. */ @@ -328,21 +327,25 @@ void MainWindow::onStart(){ if (row < 0){ say(LOG_ERROR, tr("no backup item selected")); } else { - startStop(true); - const BackupItem& item = m_configuration.items().at(row); - delete m_searchTask; + const BackupItem& item = m_configuration.items().at(row); BackupEngine::m_searchReady = false; - QString target = buildTargetDir(item.m_target); - ReQStringUtils::ensureLastChar(target, OS_SEPARATOR); - m_searchTask = new SearchTask(item.m_name, - item.m_filePatterns, item.m_dirPatterns, - item.m_sources, target, this); - m_searchTask->start(); - delete m_backupTask; - m_backupTask = new BackupTask(item.m_name, item.m_sources, target, - this); - m_backupTask->start(); - } + QString target = BackupUtils::findTarget(item, &m_logger); + if (target.isEmpty()){ + say(LOG_ERROR, tr("Target not available")); + } else { + ReQStringUtils::ensureLastChar(target, OS_SEPARATOR); + startStop(true); + delete m_searchTask; + m_searchTask = new SearchTask(item.m_name, + item.m_filePatterns, item.m_dirPatterns, + item.m_sources, target, this); + m_searchTask->start(); + delete m_backupTask; + m_backupTask = new BackupTask(item.m_name, item.m_sources, target, + this); + m_backupTask->start(); + } + } } /** * Stops the backup. @@ -485,7 +488,7 @@ void MainWindow::updateTableRow(int row, BackupItem& item, QTableWidget* target) target->setItem(row, base + 0, new QTableWidgetItem(item.m_name)); target->setItem(row, base + 1, new QTableWidgetItem(item.m_target)); target->setItem(row, base + 2, new QTableWidgetItem(! item.m_lastBackup.isValid() ? "" : - item.m_lastBackup.toString("yyyy.MM.dd hh:mm"))); + BackupUtils::dateToString(item.m_lastBackup))); target->setItem(row, base + 3, new QTableWidgetItem(item.m_sources.join(" "))); } } diff --git a/appl/rebackgui/mainwindow.hpp b/appl/rebackgui/mainwindow.hpp index ef63a8e..0305348 100644 --- a/appl/rebackgui/mainwindow.hpp +++ b/appl/rebackgui/mainwindow.hpp @@ -32,9 +32,10 @@ public: void startStop(bool isStart); void restoreState(); void saveState(); +private: + QString extractTarget(const QString& dir); private slots: virtual void aboutToQuit(); - void findTarget(const QString& dir); virtual void guiTimerUpdate(); void onAbout(); void onAddItem(); @@ -62,7 +63,7 @@ private: int m_currentRowBackup; QString m_lastSource; SearchTask* m_searchTask; - BackupTask* m_backupTask; + BackupTask* m_backupTask; }; #endif // MAINWINDOW_HPP diff --git a/appl/rebackgui/rebackgui.pro b/appl/rebackgui/rebackgui.pro index 49b131a..9d8b608 100644 --- a/appl/rebackgui/rebackgui.pro +++ b/appl/rebackgui/rebackgui.pro @@ -1,46 +1,51 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-01-18T00:51:17 -# -#------------------------------------------------- - -QT += core gui - -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -TARGET = rebackgui -TEMPLATE = app -INCLUDEPATH = ../.. /usr/include/c++/4.9 - -SOURCES += main.cpp\ - ../../base/ReException.cpp \ - ../../base/ReQStringUtils.cpp \ - ../../base/ReFileUtils.cpp \ - ../../base/ReMatcher.cpp \ - ../../base/ReLogger.cpp \ - ../../gui/ReStateStorage.cpp \ - ../../gui/ReGuiApplication.cpp \ - ../../gui/ReGuiValidator.cpp \ - ../../gui/ReGuiQueue.cpp \ - mainwindow.cpp \ - aboutdialog.cpp \ - Configuration.cpp \ - BackupEngine.cpp - -HEADERS += mainwindow.hpp \ - ../../base/rebase.hpp \ - ../../base/ReQStringUtils.hpp \ - ../../gui/ReStateStorage.hpp \ - ../../gui/ReGuiValidator.hpp \ - ../../gui/regui.hpp \ - aboutdialog.hpp \ - Configuration.hpp \ - backupgui.hpp \ - BackupEngine.hpp - -FORMS += mainwindow.ui \ - aboutdialog.ui - -DISTFILES += \ - ReBackGui.html - +#------------------------------------------------- +# +# Project created by QtCreator 2016-01-18T00:51:17 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = rebackgui +TEMPLATE = app +INCLUDEPATH = ../.. /usr/include/c++/4.9 + +SOURCES += main.cpp\ + ../../base/ReException.cpp \ + ../../base/ReConfig.cpp \ + ../../base/ReQStringUtils.cpp \ + ../../base/ReFileUtils.cpp \ + ../../base/ReMatcher.cpp \ + ../../base/ReLogger.cpp \ + ../../base/ReRandomizer.cpp \ + ../../base/ReStringUtils.cpp \ + ../../gui/ReStateStorage.cpp \ + ../../gui/ReGuiApplication.cpp \ + ../../gui/ReGuiValidator.cpp \ + ../../gui/ReGuiQueue.cpp \ + mainwindow.cpp \ + aboutdialog.cpp \ + Configuration.cpp \ + BackupEngine.cpp \ + BackupUtils.cpp + +HEADERS += mainwindow.hpp \ + ../../base/rebase.hpp \ + ../../base/ReQStringUtils.hpp \ + ../../gui/ReStateStorage.hpp \ + ../../gui/ReGuiValidator.hpp \ + ../../gui/regui.hpp \ + aboutdialog.hpp \ + Configuration.hpp \ + backupgui.hpp \ + BackupEngine.hpp \ + BackupUtils.hpp + +FORMS += mainwindow.ui \ + aboutdialog.ui + +DISTFILES += \ + ReBackGui.html + diff --git a/base/ReConfig.cpp b/base/ReConfig.cpp index dffdb11..8ecac97 100644 --- a/base/ReConfig.cpp +++ b/base/ReConfig.cpp @@ -54,7 +54,8 @@ ReConfig::ReConfig(const char* file, bool readOnly, ReLogger* logger) : m_lineList(), m_readOnly(readOnly), m_logger(logger), - m_ownLogger(logger == NULL) { + m_ownLogger(logger == NULL), + m_modified(false){ if (logger == NULL) { initLogger(); } @@ -68,6 +69,8 @@ ReConfig::ReConfig(const char* file, bool readOnly, ReLogger* logger) : * Frees the resources. */ ReConfig::~ReConfig() { + if (! m_readOnly && m_modified) + write(m_file); if (m_ownLogger) delete m_logger; m_logger = NULL; @@ -134,7 +137,44 @@ QByteArray ReConfig::asString(const char* key, const char* defaultValue) { if (contains(key)) { rc = (*this)[key]; } - return rc; + return rc; +} + +/** + * Puts a boolean variable into the configuration. + * + * @param key the key of the variable + * @param value the value of the variable + */ +void ReConfig::put(const char *key, bool value) +{ + put(key, value ? "true" : "false"); +} + +/** + * Puts an integer variable into the configuration. + * + * @param key the key of the variable + * @param value the value of the variable + */ +void ReConfig::put(const char *key, int value) +{ + put(key, QByteArray::number(value).constData()); +} + +/** + * Puts a string variable into the configuration. + * + * @param key the key of the variable + * @param value the value of the variable + */ +void ReConfig::put(const char *key, const char *value) +{ + m_modified = true; + if (! contains(key)){ + m_lineList.append(key + QByteArray("=")); + } + insert(key, value); } /** @@ -147,6 +187,8 @@ QByteArray ReConfig::asString(const char* key, const char* defaultValue) { bool ReConfig::read(const char* file) { bool rc = true; m_lineList.reserve(1024); + if (file == NULL) + file = m_file.constData(); FILE* fp = fopen(file, "r"); if (fp == NULL) { m_logger->logv(LOG_ERROR, LOC_READ_1, "cannot read: %s", file); @@ -187,9 +229,27 @@ bool ReConfig::write(const char* file) { if (m_readOnly) m_logger->log(LOG_ERROR, LOC_WRITE_1, "cannot write: (readonly"); else { - m_logger->logv(LOG_ERROR, LOC_WRITE_2, "not implemented: write(%s)", - file); - } + if (file == NULL){ + file = m_file.constData(); + } + int pos = 0; + QByteArray key; + FILE* fp = fopen(file, "w"); + if (fp == NULL) + m_logger->logv(LOG_ERROR, LOC_WRITE_2, "cannot open (%d): %s", errno, file); + else { + for (int ix = 0; ix < m_lineList.size(); ix++){ + QByteArray& line = m_lineList[ix]; + if (isalnum(line[0]) && (pos = line.indexOf('=')) >= 0) { + key = line.mid(0, pos); + if (contains(key)) + line = key + "=" + value(key) + "\n"; + } + fputs(line.constData(), fp); + } + fclose(fp); + } + } return rc; } diff --git a/base/ReConfig.hpp b/base/ReConfig.hpp index cb8ee06..a862ed0 100644 --- a/base/ReConfig.hpp +++ b/base/ReConfig.hpp @@ -11,30 +11,34 @@ #ifndef RECONFIG_HPP #define RECONFIG_HPP -class ReConfig: public ReConfigurator, public QHash { +class ReConfig: public ReConfigurator, protected QHash { public: ReConfig(const char* file = NULL, bool readOnly = true, ReLogger* logger = NULL); virtual ~ReConfig(); public: - bool read(const char* file); - bool write(const char* file); - void clear(); - const QList& getLines() const; - virtual bool asBool(const char* key, bool defaultValue) const; virtual int asInt(const char* key, int defaultValue) const; virtual QByteArray asString(const char* key, const char* defaultValue); + void clear(); + const QList& getLines() const; + 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); + private: void initLogger(); private: - const char* m_file; - QList m_lineList; + QByteArray m_file; + QByteArrayList m_lineList; bool m_readOnly; ReLogger* m_logger; // true: the logger must be destroyed in the destructor bool m_ownLogger; + bool m_modified; }; #endif // RECONFIG_HPP diff --git a/base/ReFile.cpp b/base/ReFile.cpp index 3248413..ae1bad8 100644 --- a/base/ReFile.cpp +++ b/base/ReFile.cpp @@ -17,7 +17,7 @@ enum { LOC_DELETE_TREE_3, // 11803 }; -#if defined __linux__ || defined WIN32 +#if defined __linux__ || defined _WIN32 void* memichr(void* heap, int cc, size_t length) { const char* heap2 = reinterpret_cast(heap); int cc2 = tolower(cc); @@ -30,7 +30,8 @@ void* memichr(void* heap, int cc, size_t length) { } return rc; } - +#endif /* __linux__ */ +#if defined __linux__ int memicmp(const void* str1, const void* str2, size_t length) { const char* str12 = reinterpret_cast(str1); const char* str22 = reinterpret_cast(str2); @@ -44,8 +45,7 @@ int memicmp(const void* str1, const void* str2, size_t length) { } return rc; } -#endif /* __linux__ */ - +#endif /** * Constructor. */ diff --git a/base/ReFileUtils.cpp b/base/ReFileUtils.cpp index fe2b822..e2bae9e 100644 --- a/base/ReFileUtils.cpp +++ b/base/ReFileUtils.cpp @@ -10,7 +10,6 @@ */ #include "base/rebase.hpp" - enum { LOC_DELETE_TREE_1 = LOC_FIRST_OF(LOC_FILE_UTILS), // 12501 LOC_DELETE_TREE_2, // 12502 @@ -45,7 +44,7 @@ QByteArray ReFileUtils::cleanPath(const char* path) { int length = strlen(path); rc.reserve(length); int minLength = 0; -#ifdef __WIN32__ +#ifdef _WIN32 // UNC path, e.g. "\\server\share"? if ((path[0] == OS_SEPARATOR || path[0] == OS_2nd_SEPARATOR) && (path[1] == OS_SEPARATOR || path[1] == OS_2nd_SEPARATOR)) { @@ -231,7 +230,29 @@ QByteArray ReFileUtils::extensionOf(const char* filename) { ix--; } } - return rc; + return rc; +} + +/** + * Returns the list of root filesystems. + * + * Windows: the list of available drives + * + * @return the list of root directories + */ +QStringList ReFileUtils::findRootDirs() +{ + QStringList rc; +#if defined __linux__ + rc.append("/"); +#elif defined _WIN32 + QFileInfoList drives = QDir::drives(); + QFileInfoList::const_iterator it; + for (it = drives.cbegin(); it != drives.cend(); ++it){ + rc.append(it->absolutePath().mid(0, 2)); + } +#endif + return rc; } /** @@ -282,11 +303,12 @@ bool ReFileUtils::isDirectory(const QString& path, bool* isFile) QFileInfo info(path); bool rc = info.exists(); if (rc){ - if (isFile != NULL) - *isFile = true; if (! info.isDir()) rc = false; - } + if (isFile != NULL) + *isFile = ! rc; + } else if (isFile != NULL) + *isFile = false; return rc; } @@ -300,8 +322,8 @@ bool ReFileUtils::isRootDir(const char* path) { #if defined __linux__ return path[0] == OS_SEPARATOR && path[1] == '\0'; -#elif defined WIN32 - return isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && path[3] = '\0'; +#elif defined _WIN32 + return isalpha(path[0]) && path[1] == ':' && path[2] == '\\' && path[3] == '\0'; #endif } @@ -349,26 +371,39 @@ bool ReFileUtils::makeDir(const QString& path, ReLogger* logger) { * false: error occurred */ bool ReFileUtils::makeDirWithParents(const char* path, ReLogger* logger) { - const char* end; - const char* start = path; - bool rc = true; - QByteArray dir; - while (rc && (end = strchr(start, OS_SEPARATOR)) != NULL) { - if (end == path) { - start++; - dir += OS_SEPARATOR; - } else { - dir.append(start, end - start); - start = end + 1; - rc = makeDir(dir.constData(), logger); - dir += OS_SEPARATOR; - } - } - if (rc && start[0] != '\0') { - dir.append(start); - rc = makeDir(dir.constData(), logger); - } - return rc; + struct stat info; + bool rc = false; + if (stat(path, &info) == 0 && S_ISDIR(info.st_mode)){ + rc = true; + } else { + QByteArray dir = ReStringUtils::chomp(parentOf(path), OS_SEPARATOR); + if (stat(dir.constData(), &info) == 0 && S_ISDIR(info.st_mode)) + rc = makeDir(path, logger); + else { + const char* end; + const char* start = path; + while (rc && (end = strchr(start, OS_SEPARATOR)) != NULL) { + if (end == path) { + start++; + dir += OS_SEPARATOR; + } else { + dir.append(start, end - start); + start = end + 1; +#if defined _WIN32 + if (dir.length() == 2 && dir.at(1) == ':') + continue; +#endif + rc = makeDir(dir.constData(), logger); + dir += OS_SEPARATOR; + } + } + if (rc && start[0] != '\0') { + dir.append(start); + rc = makeDir(dir.constData(), logger); + } + } + } + return rc; } /** @@ -440,19 +475,40 @@ QByteArray ReFileUtils::nodeOf(const char* filename) { * trailing separator */ QString ReFileUtils::parentOf(const QString& filename) { - QString rc; + QString rc; + + int ix = filename.size() - 1; + while (ix >= 0) { + if (filename[ix] == '/' || filename[ix] == '\\') { + rc = filename.mid(0, ix + 1); + break; + } + ix--; + } + return rc; +} - int ix = filename.size() - 1; - while (ix >= 0) { - if (filename[ix] == '/' || filename[ix] == '\\') { - rc = filename.mid(ix + 1); - break; - } - ix--; - } - if (ix >= 0) - rc = filename.mid(0, ix + 1); - return rc; +/** + * Extracts the path of a full filename. + * + * @param filename the filename (with or without path) + * @return "": no path available
+ * "/": filename = "/"
+ * otherwise: the path of filename including + * trailing separator + */ +QByteArray ReFileUtils::parentOf(const char* filename) { + QByteArray rc; + + int ix = strlen(filename) - 1; + while (ix >= 0) { + if (filename[ix] == '/' || filename[ix] == '\\') { + rc.append(filename, ix + 1); + break; + } + ix--; + } + return rc; } /** @@ -652,8 +708,17 @@ bool ReFileUtils::setTimes(const char* filename, const QDateTime& modified, "cannot change times (%d): $s", errno, filename); rc = false; } -#elif defined __WIN32__ -#error "not implemented" +#else + // ANSII-C: + struct utimbuf times; + times.actime = time_t(accessed.currentMSecsSinceEpoch() / 1000); + times.modtime = time_t(modified.currentMSecsSinceEpoch() / 1000); + int rc2 = utime(filename, ×); + if (rc2 != 0 && logger != NULL){ + logger->logv(LOG_ERROR, LOC_SET_TIMES_1, + "cannot change times (%d): $s", errno, filename); + rc = false; + } #endif return rc; } @@ -671,8 +736,8 @@ int ReFileUtils::seek(FILE* file, int64_t offset, int whence) { int rc; #if defined __linux__ rc = fseeko(file, offset, whence); -#elif defined __WIN32__ - rc = _fseek64(file, offset, whence); +#elif defined _WIN32 + rc = _fseeki64(file, offset, whence); #endif return rc; } @@ -688,8 +753,8 @@ int64_t ReFileUtils::tell(FILE* file) { int64_t rc; #if defined __linux__ rc = ftello(file); -#elif defined __WIN32__ - rc = _ftell64(file); +#elif defined _WIN32 + rc = _ftelli64(file); #endif return rc; } @@ -710,7 +775,7 @@ QByteArray ReFileUtils::tempDir(const char* node, const char* parent, QByteArray temp("/tmp"); static const char* firstVar = "TMP"; static const char* secondVar = "TEMP"; -#elif defined WIN32 +#elif defined _WIN32 QByteArray temp("c:\\temp"); static const char* firstVar = "TEMP"; static const char* secondVar = "TMP"; @@ -721,7 +786,7 @@ QByteArray ReFileUtils::tempDir(const char* node, const char* parent, temp = ptr; else if ((ptr = getenv(secondVar)) != NULL) temp = ptr; -#if defined WIN32 +#if defined _WIN32 temp.replace('\\', '/'); #endif if (temp.at(temp.length() - 1) != '/') diff --git a/base/ReFileUtils.hpp b/base/ReFileUtils.hpp index 5ba8f07..db12853 100644 --- a/base/ReFileUtils.hpp +++ b/base/ReFileUtils.hpp @@ -34,6 +34,7 @@ public: static QString cleanPath(const QString& path); static QString extensionOf(const QString& filename); static QByteArray extensionOf(const char* filename); + static QStringList findRootDirs(); static bool isAbsolutPath(const QString& path); static bool isAbsolutPath(const char* path); static bool isDirectory(const QString& path, bool* isFile = NULL); @@ -71,6 +72,7 @@ public: static QString nodeOf(const QString& filename); static QByteArray nodeOf(const char* filename); static QString parentOf(const QString& filename); + static QByteArray parentOf(const char* filename); static QString pathAppend(const QString& base, const QString& path); static QByteArray pathAppend(const char* base, const char* path); static QByteArray& readFromFile(const char* filename, QByteArray& buffer); diff --git a/base/ReQStringUtils.cpp b/base/ReQStringUtils.cpp index 350f7c2..b5fcf72 100644 --- a/base/ReQStringUtils.cpp +++ b/base/ReQStringUtils.cpp @@ -517,18 +517,18 @@ QString ReQStringUtils::readableDuration(qint64 duration){ rc = QString::number(duration2, 'f', 3) + " sec"; } else if (duration2 < 3600.0){ int duration3 = int(duration2); - snprintf(buffer, sizeof buffer, "%d:%02d", + _snprintf(buffer, sizeof buffer, "%d:%02d", duration3 / 60, duration3 % 60); rc = buffer; } else if (duration2 < 3600.0 * 24){ int duration3 = int(duration2); - snprintf(buffer, sizeof buffer, "%d:%02d:%02d", + _snprintf(buffer, sizeof buffer, "%d:%02d:%02d", duration3 / 3600, duration3 % 3600 / 60, duration3 % 60); rc = buffer; } else { int duration3 = int(duration2); - snprintf(buffer, sizeof buffer, "%d:%02d:%02d:%02d", + _snprintf(buffer, sizeof buffer, "%d:%02d:%02d:%02d", int(duration3 / (3600*24)), int(duration3 % (3600*24) / 3600), int(duration3 % 3600 / 60), int(duration3 % 60)); diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index e2dd05e..92ce55f 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -393,7 +393,27 @@ ReRandomizer::seed_t ReRandomizer::nearTrueRandom() { rc ^= buffer; close(fh); #endif - return rc; + return rc; +} + +/** + * Returns a unique identifier. + * + * @param readable true: the string is divided with '-' (every 4 chars) + * @return a BASE64 encoded near true random value (96 bit) + */ +QByteArray ReRandomizer::buildUUID(bool readable) +{ + QByteArray uuid; + uint8_t buffer[2 * sizeof(seed_t)]; + reinterpret_cast(buffer)[0] = nearTrueRandom(); + reinterpret_cast(buffer)[1] = nearTrueRandom(); + ReStringUtils::base64Encode(buffer, 12, uuid); + if (readable){ + for (int ix = 12; ix > 0; ix -= 4) + uuid.insert(ix, '-'); + } + return uuid; } /** @@ -1059,7 +1079,7 @@ void ReKISSRandomizer::saveSeed(QByteArray& seed) const { */ QByteArray ReKISSRandomizer::state() const{ char buffer[512]; - snprintf(buffer, sizeof buffer, + _snprintf(buffer, sizeof buffer, "%2d: f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx", m_counter, (long long) m_factor, (long long) m_increment, diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index 7fd1f54..21cbdc6 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -156,6 +156,7 @@ public: static void hash(const QByteArray& text, QByteArray& seed); static seed_t pseudoTrueRandom(); static seed_t nearTrueRandom(); + static QByteArray buildUUID(bool readable = true); protected: QByteArray m_name; int m_counter; diff --git a/base/ReStringUtils.cpp b/base/ReStringUtils.cpp index efb9cf1..9e2c8ea 100644 --- a/base/ReStringUtils.cpp +++ b/base/ReStringUtils.cpp @@ -27,6 +27,73 @@ const char ReStringUtils::AUTO_SEPARATOR = '\0'; const QByteArray ReStringUtils::m_empty; +static const char* m_base64Chars = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +/** + * Transforms a BASE64 string into a byte array. + * + * @param input the string to decode + * @param inputLength the length of the string to decode. If -1 strlen() will be taken + * @param output OUT: the decoded bytes + * @return output (for chaining) + */ +QByteArray& ReStringUtils::base64Decode(const char* input, int inputLength, QByteArray& output) { + static uint8_t decoder[256] = {0}; + if (decoder['A'] == 0){ + for (int ix = strlen(m_base64Chars) - 1; ix >= 0; ix--) + decoder[m_base64Chars[ix]] = ix; + } + int fillBytes = 0; + while(inputLength > 0 && input[inputLength - 1] == '='){ + fillBytes++; + inputLength--; + } + output.resize((inputLength + 3) * 3 / 4); + uint8_t* outCursor = reinterpret_cast(output.data()); + while(inputLength > 4){ + *outCursor++ = decoder[(input[0] << 2) + ((input[1] & 0x30) >> 4)]; + *outCursor++ = decoder[((input[1] & 0xf) << 4) + ((input[2] & 0x3c) >> 2)]; + *outCursor++ = decoder[((input[2] & 0x3) << 6) + input[3]]; + inputLength -= 4; + input += 4; + } + return output; +} + +/** + * Transforms a byte array into a BASE64 string. + * + * @param input the byte array to encode + * @param inputLength the length of the byte array to encode + * @param output OUT: the encoded string + * @return output (for chaining) + */ +QByteArray& ReStringUtils::base64Encode(uint8_t const* input, size_t inputLength, QByteArray& output) { + output.resize(4 * ((inputLength + 2 - ((inputLength + 2) % 3)) / 3)); + uint8_t* outCursor = reinterpret_cast(output.data()); + while (inputLength-- > 3) { + *outCursor++ = m_base64Chars[(input[0] & 0xfc) >> 2]; + *outCursor++ = m_base64Chars[((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4)]; + *outCursor++ = m_base64Chars[((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6)]; + *outCursor++ = m_base64Chars[input[2] & 0x3f]; + input += 3; + inputLength -= 3; + } + if (inputLength > 0){ + uint8_t buffer[3]; + memset(buffer, 0, sizeof buffer); + memcpy(buffer, input, 3 - inputLength); + *outCursor++ = m_base64Chars[(input[0] & 0xfc) >> 2]; + *outCursor++ = m_base64Chars[((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4)]; + *outCursor++ = m_base64Chars[((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6)]; + *outCursor++ = m_base64Chars[input[2] & 0x3f]; + for (int ii = inputLength; ii <= 3; ii++) + *outCursor++ = '='; + } + return output; +} /** * Removes a given character from the end of the string if it is there. @@ -114,6 +181,7 @@ const QByteArray& ReStringUtils::cutString(const QByteArray& source, } static char s_fileSeparator = 0; + /** * @brief Returns the os specific file path separator. * @return the file path separator, e.g. "/" for linux diff --git a/base/ReStringUtils.hpp b/base/ReStringUtils.hpp index b443eab..c83eb69 100644 --- a/base/ReStringUtils.hpp +++ b/base/ReStringUtils.hpp @@ -8,8 +8,8 @@ * More info: http://unlicense.org * The latest sources: https://github.com/republib */ -#ifndef RPLSTRING_HPP -#define RPLSTRING_HPP +#ifndef RESTRING_HPP +#define RESTRING_HPP #ifdef __linux__ #define strnicmp(trg, src, len) strncasecmp(trg, src, len) @@ -44,6 +44,8 @@ protected: class ReStringUtils { public: + static QByteArray& base64Decode(const char *input, int inputLength, QByteArray& output); + static QByteArray& base64Encode(const uint8_t *input, size_t inputLength, QByteArray& output); static QByteArray& chomp(QByteArray &string, char cc = '\n'); static int countChar(const char* line, char cc); static int count(const char* source, const char* item); @@ -90,4 +92,4 @@ public: static const char AUTO_SEPARATOR; }; -#endif // RPLSTRING_HPP +#endif // RESTRING_HPP diff --git a/base/ReTest.cpp b/base/ReTest.cpp index 1b5dbb4..335b634 100644 --- a/base/ReTest.cpp +++ b/base/ReTest.cpp @@ -462,9 +462,9 @@ void ReTest::assertLogContainsLocation(int location, const char* file, int lineN void ReTest::ensureNotExist(const char* fullname) { if (exists(fullname)) - unlink(fullname); + _unlink(fullname); if (exists(fullname) && exists(fullname, true)) - rmdir(fullname); + _rmdir(fullname); if (exists(fullname)) error("cannot delete (%d): %s", errno, fullname); } @@ -528,14 +528,14 @@ QByteArray ReTest::getTempDir(const char* node, const char* parent, if (parent != NULL) { temp += parent; if (stat(temp.constData(), &info) != 0) - mkdir(temp.constData(), (-1)); + _mkdir(temp.constData()); temp += sep; } if (node != NULL) { temp += node; temp += sep; if (stat(temp.data(), &info) != 0) - mkdir(temp.data(), -1); + _mkdir(temp.data()); } if (!withSeparator) temp.resize(temp.length() - 1); @@ -559,7 +559,7 @@ QByteArray ReTest::getTempFile(const char* node, const char* parent, rc += node; struct stat info; if (deleteIfExists && stat(rc.constData(), &info) == 0) - unlink(rc.constData()); + _unlink(rc.constData()); return rc; } /** diff --git a/base/rebase.hpp b/base/rebase.hpp index a80380e..e661449 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -24,10 +24,12 @@ #include #include #include -#else +#elif defined _WIN32 #include #include +#include #endif + #include #include #include @@ -61,7 +63,10 @@ typedef quint32 uint32_t; typedef qreal real_t; typedef QString ReString; #define RE_UNUSED(x) (void)(x) - +#ifdef _WIN32 +typedef quint64 uint64_t; +typedef short int int16_t; +#endif #ifdef __linux__ #define _strcasecmp strcasecmp #define OS_SEPARATOR '/' @@ -74,6 +79,7 @@ typedef QString ReString; #define _unlink unlink //typedef qint64 uint64_t; #else +#define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0) #define _strcasecmp _stricmp #define OS_SEPARATOR '\\' #define OS_SEPARATOR_STR "\\" diff --git a/cunit/cuReFileSystem.cpp b/cunit/cuReFileSystem.cpp index 870ae66..e292f27 100644 --- a/cunit/cuReFileSystem.cpp +++ b/cunit/cuReFileSystem.cpp @@ -197,15 +197,19 @@ protected: #endif checkEqu(owner, p1.m_user); checkEqu(group, p1.m_group); +#ifdef __linux__ checkEqu( S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH, p1.m_fileMode); checkEqu(S_IWUSR | S_IRUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | __S_IFDIR, p1.m_dirMode); +#endif ReOSPermissions p2(p1); checkEqu(owner, p2.m_user); checkEqu(group, p2.m_group); - checkEqu( S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH, p2.m_fileMode); +#ifdef __linux__ + checkEqu( S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP | S_IROTH, p2.m_fileMode); checkEqu(S_IWUSR | S_IRUSR | S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH | __S_IFDIR, p2.m_dirMode); +#endif p2.m_user = 0x4711; p2.m_group = 0x1147; p2.m_dirMode = 123; diff --git a/cunit/cuReFileUtils.cpp b/cunit/cuReFileUtils.cpp index 8db20b2..af4f614 100644 --- a/cunit/cuReFileUtils.cpp +++ b/cunit/cuReFileUtils.cpp @@ -45,7 +45,7 @@ public: ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true)); QByteArray subdir(dir); subdir.append("subdirX"); - mkdir(subdir.constData(), ALLPERMS); + _mkdir(subdir.constData()); struct stat info; checkEqu(0, stat(subdir.constData(), &info)); ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true); @@ -65,13 +65,13 @@ public: QByteArray base = ReFileUtils::tempDir("ReFileUtils"); for (char cc = 'a'; cc < 'f'; cc++) { QByteArray subdir(base + cc); - mkdir(subdir.constData(), ALLPERMS); + _mkdir(subdir.constData()); for (char cc2 = '1'; cc2 < '5'; cc2++) { QByteArray name(subdir); name.append(OS_SEPARATOR_STR).append(&cc2, 1); ReFileUtils::writeToFile(name, name); name += "dir"; - mkdir(name.constData(), ALLPERMS); + _mkdir(name.constData()); name.append(OS_SEPARATOR_STR).append("x.txt"); ReFileUtils::writeToFile(name, name); } @@ -87,7 +87,7 @@ public: // the dir must exist: checkEqu(0, stat(base, &info)); // rmdir() works only if the dir is empty: - checkEqu(0, rmdir(base)); + checkEqu(0, _rmdir(base)); buildTree(); checkT(ReFileUtils::deleteTree(QString(base), false, &m_logger)); checkEqu(0, stat(base, &info)); diff --git a/cunit/cuReProcess.cpp b/cunit/cuReProcess.cpp index a71774b..2dfc65d 100644 --- a/cunit/cuReProcess.cpp +++ b/cunit/cuReProcess.cpp @@ -28,6 +28,13 @@ private: QByteArray id = ReProcess::executeAndRead(QString("/usr/bin/id"), args); checkF(id.isEmpty()); +#elif defined _WIN32 + QStringList args; + args.append("/c"); + args.append("dir"); + args.append("c:\\"); + QByteArray id = ReProcess::executeAndRead(QString("cmd"), args); + checkF(id.isEmpty()); #else #error "missing test" #endif diff --git a/gui/ReGuiApplication.cpp b/gui/ReGuiApplication.cpp index efa918a..bbe0734 100644 --- a/gui/ReGuiApplication.cpp +++ b/gui/ReGuiApplication.cpp @@ -79,7 +79,7 @@ QString ReGuiApplication::fileOfHome(const QString& node) QString ReGuiApplication::buildHomeDir(QString homeDirBase, const QString& node){ QString homeDir; if (homeDirBase.isEmpty()){ - homeDir = QDir::home().absoluteFilePath(node); + homeDir = ReFileUtils::nativePath(QDir::home().absoluteFilePath(node)); } else if (ReFileUtils::isRootDir(homeDirBase.toLatin1().constData())){ homeDir = homeDirBase + node; } diff --git a/os/ReFileSystem.cpp b/os/ReFileSystem.cpp index a99bf01..a3ac04b 100644 --- a/os/ReFileSystem.cpp +++ b/os/ReFileSystem.cpp @@ -45,6 +45,9 @@ ReFileSystem::ReFileSystem(const QString& name, ReLogger* logger) : #ifdef __linux__ m_uid(geteuid()), m_gid(getegid()), +#else + m_uid(0), + m_gid(0), #endif m_writeable(false), m_logger(logger), diff --git a/os/ReFileSystem.hpp b/os/ReFileSystem.hpp index 58e8795..3ee7379 100644 --- a/os/ReFileSystem.hpp +++ b/os/ReFileSystem.hpp @@ -225,10 +225,8 @@ public: static ReFileSystem* buildFromUrl(const QString& url); protected: QString m_name; -#ifdef __linux__ int m_uid; int m_gid; -#endif // ending with OS_SEPARATOR: QString m_directory; // All links are replaced by its targets: diff --git a/os/reos.hpp b/os/reos.hpp index e9b302d..a0baffc 100644 --- a/os/reos.hpp +++ b/os/reos.hpp @@ -19,7 +19,7 @@ #include #include #include -#elif defined __WIN32__ +#elif defined _WIN32 #include #include "windows.h" #include @@ -30,9 +30,10 @@ #if defined __linux__ typedef struct timespec ReFileTime_t; typedef __off_t ReFileSize_t; -#elif defined __WIN32__ +#elif defined _WIN32 typedef FILETIME ReFileTime_t; typedef int64_t ReFileSize_t; +typedef unsigned short mode_t; #endif /** Returns whether a time is greater (younger) than another. * @param time1 first operand -- 2.39.5