*/
#include "backupgui.hpp"
+enum {
+ LOC_FIND_TARGET_1 = LOC_FIRST_OF(LOC_REBACKGUI_BACKUPUTILS), // 20501
+ LOC_FIND_TARGET_2, // 20502
+};
+
+
BackupUtils::BackupUtils()
{
-
}
/**
* Converts a date time to a string.
{
QString rc;
#if defined __linux__
- if (item.m_target.startsWith(";/")){
+ 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 {
-
+ 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));
+ }
}
#elif defined _WIN32
QStringList drives = ReFileUtils::findRootDirs();
return rc;
}
+QString BackupUtils::targetDescription(const QString& backupPath, ReLogger *logger){
+ QString rc;
+#if defined __linux__
+ if (true){
+ // nothing to do
+ } else if (true){
+ // the path is an absolute path on a fixed disk:
+ } else {
+ QStringList args;
+ args << "/usr/local/bin/osconnect.pl"
+ << "find-label"
+ << backupPath
+ << "/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));
+ }
+ }
+#elif defined _WIN32
+#endif
+ return rc;
+}
* More info: http://unlicense.org
* The latest sources: https://github.com/republib
*/
-#ifndef BACKUPUTILS_H\r
-#define BACKUPUTILS_H\r
-\r
-\r
-class BackupUtils\r
-{\r
-public:\r
- BackupUtils();\r
-public:\r
- static QString dateToString(const QDateTime& dateTime);\r
- static QString findTarget(const BackupItem& item, ReLogger* logger);\r
- static QString nameOfTargetDescription(const QString &path);\r
- static bool prepareTarget(const QString &path, BackupItem &item, ReLogger *logger);\r
- static QDateTime stringToDate(const QString& dateTime);\r
-};\r
-\r
-#endif // BACKUPUTILS_H\r
+#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);
+ static QString targetDescription(const QString& backupPath, ReLogger *logger);
+};
+
+#endif // BACKUPUTILS_H
if (! BackupUtils::prepareTarget(dir, item, &m_logger))
say(LOG_INFO, tr("target initialized with %1")
.arg(BackupUtils::nameOfTargetDescription(dir)));
+ else {
+ item.m_target = BackupUtils::targetDescription(dir, &m_logger);
+ }
}
}
my %devs;
my (%g_devOfPoint, %g_pointOfDev, %g_devOfLabel, %g_labelOfDev);
-&FindLabels;
-&FindMountPoints;
if ($mode eq "find-label"){
my $targetPath = shift;
if (! -d $targetPath){
&Usage("not a directory: $targetPath");
}
+ &FindLabels;
+ &FindMountPoints;
&PrintLabelAndRelPath($targetPath);
} elsif ($mode eq "search-target"){
my $label = shift;
my $relPath = shift;
+ my $testDir = shift;
+ $label =~ s/L=//;
&Usage("missing label") unless $label;
&Usage("missing relative path") unless $relPath;
- my $dev = %g_devOfLabel{$label};
- if ($dev ne ""){
- my $mountPoint = $g_pointOfDev{$dev};
- if ($mountPoint ne ""){
- print "$mountPoint/$relPath\n";
+ if ($testDir ne ""){
+ print "$testDir\nmounted\n";
+ } else {
+ &FindLabels;
+ &FindMountPoints;
+ my $dev = %g_devOfLabel{$label};
+
+ if ($dev ne ""){
+ my $mountPoint = $g_pointOfDev{$dev};
+ if ($mountPoint ne ""){
+ print "$mountPoint/$relPath\nmounted\n";
+ } else {
+ $mountPoint = $label;
+ $mountPoint =~ s/[^\w!=%.+-]+/_/g;
+ $mountPoint =~ s/__+/_/g;
+ $mountPoint = "/media/$mountPoint";
+ mkdir $mountPoint, 0777 unless $mountPoint;
+ my $dir = $mountPoint;
+ my $no = 1;
+ while(IsMounted($dir)){
+ $dir = $mountPoint . ++$no;
+ }
+ $mountPoint = $dir;
+ mkdir $mountPoint, 0777 unless -d $mountPoint;
+ Exec("mount 'LABEL=$label' $mountPoint");
+ &FindMountPoints;
+ $dir = "$mountPoint/$relPath";
+ my $isMounted = IsMounted($mountPoint);
+ if ($isMounted && -d $dir){
+ print "$dir\nunmounted\n";
+ } else {
+ my $error = ! $isMounted ? "cannot mount '$label' to $mountPoint"
+ : "missing $relPath on '$label'";
+ print "\n+++ $error\n";
+ }
+ }
}
}
} else {
Output:
L=<label>
<relative_path>
-osconnect mount-target <label> <rel_path>
- Search the device with a given label and mount it (if not mounted)
+osconnect search-target <label> <rel_path>
+ Search the device with a given label and mount it (if not mounted).
+ <flag>: "mounted": device was already mounted
+ "unmounted": device has been mounted by the script
+ "+++ <msg>": mount not possible: <msg> is error message
Output:
- <mount-directory>
+ <backup-directory>
<flag>
-Example:
+Examples:
osconnect.pl find-label /media/USB-black/backup
+L=USB-Black
+backup
+osconnect.pl search-target L=USB-Black backup
+/media/trg/backup
+unmounted
EOS
print "+++", $msg, "\n";
exit 1;
# stores the relation of devices and mount points.
sub FindMountPoints{
- my $dev = shift;
open(my $CMD, "mount|") || die "cannot execute mount: $!";
my ($label, $relPath);
while(<$CMD>){
if(/(\S+) on (\S+)/){
$g_devOfPoint{$2} = $1;
$g_pointOfDev{$1} = $2;
+ # print "$1->$2#\n" if index($2, "EFI") >= 0;
}
}
close $CMD;
sub PrintLabelAndRelPath{
my $subdirOfMountpoint = shift;
my ($relPath, $label);
- for my $path (keys %g_pointOfDev){
+ for my $path (keys %g_devOfPoint){
if (index($subdirOfMountpoint, $path) == 0){
my $dev = $g_devOfPoint{$path};
if ($g_labelOfDev{$dev} ne ""){
}
}
}
+
+# Tests whether a directory is used as mount point.
+# @return 0: the directory is NOT used as mount point
+sub IsMounted{
+ my $dir = shift;
+ my $rc = $g_devOfPoint{$dir} ne "";
+}
+
+sub Exec{
+ my $cmd = shift;
+ system($cmd);
+}
SOURCES += main.cpp\
../../base/ReException.cpp \
../../base/ReConfig.cpp \
+ ../../base/ReProcess.cpp \
../../base/ReQStringUtils.cpp \
../../base/ReFileUtils.cpp \
../../base/ReMatcher.cpp \
LOC_SET_TIMES_1, // 12504
LOC_MAKE_DIR_1, // 12505
LOC_MAKE_DIR_2, // 12506
- LOC_SET_TIMES_2, // 12507
+ LOC_SET_TIMES_2, // 12507
};
QDateTime ReFileUtils::m_undefinedTime;
*/
QString ReFileUtils::copy(const QString& source, const QString& target,
const QFileInfo* sourceInfo, QByteArray& buffer){
- QString rc;
+ QString rc;
#if defined _WIN32
- const ushort* src = source.utf16();
- const ushort* trg = target.utf16();
- if (! CopyFile(reinterpret_cast<const WCHAR*>(src),
- reinterpret_cast<const WCHAR*>(trg), false))
- rc = QObject::tr("copy file failed (%1): %2")
- .arg(GetLastError()).arg(target);
+ const ushort* src = source.utf16();
+ const ushort* trg = target.utf16();
+ if (! CopyFile(reinterpret_cast<const WCHAR*>(src),
+ reinterpret_cast<const WCHAR*>(trg), false))
+ rc = QObject::tr("copy file failed (%1): %2")
+ .arg(GetLastError()).arg(target);
#else
QByteArray source2 = I18N::s2b(source);
QByteArray target2 = I18N::s2b(target);
rc = QObject::tr("file can be read only partitionally: %1 [%2/%3]")
.arg(source).arg(totalBytes).arg(filesize);
if (rc.isEmpty()){
- if (! setTimes(target2, sourceInfo->lastModified(),
+ if (! setTimes(target2.constData(), sourceInfo->lastModified(),
sourceInfo->lastRead()))
rc = QObject::tr("cannot set date/time (%1): %2")
.arg(errno).arg(target);
vals[1].tv_usec = millisec % 1000 * 1000;
if (utimes(filename, vals) != 0) {
if (logger != NULL)
- logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
- "cannot change times (%d): %s", errno, filename);
+ logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
+ "cannot change times (%d): %s", errno, filename);
rc = false;
}
#elif defined _WIN32
- // utime does not work with VS10-32-bit
- FILETIME accessed2 = unixTimeToFileTime(accessed.toMSecsSinceEpoch());
- FILETIME modified2 = unixTimeToFileTime(modified.toMSecsSinceEpoch());
+ // utime does not work with VS10-32-bit
+ FILETIME accessed2 = unixTimeToFileTime(accessed.toMSecsSinceEpoch());
+ FILETIME modified2 = unixTimeToFileTime(modified.toMSecsSinceEpoch());
- HANDLE handle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (handle == INVALID_HANDLE_VALUE){
- if (logger != NULL)
- logger->logv(LOG_ERROR, LOC_SET_TIMES_2,
- "cannot open file for time change (%d): %s", GetLastError(), filename);
- rc = false;
- } else if (! SetFileTime(handle, NULL, &accessed2, &modified2)){
- rc = false;
- if (logger != NULL)
- logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
- "cannot change times (%d): %s", errno, filename);
- CloseHandle(handle);
- }
+ HANDLE handle = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle == INVALID_HANDLE_VALUE){
+ if (logger != NULL)
+ logger->logv(LOG_ERROR, LOC_SET_TIMES_2,
+ "cannot open file for time change (%d): %s", GetLastError(), filename);
+ rc = false;
+ } else if (! SetFileTime(handle, NULL, &accessed2, &modified2)){
+ rc = false;
+ if (logger != NULL)
+ logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
+ "cannot change times (%d): %s", errno, filename);
+ CloseHandle(handle);
+ }
#else
- // QT solution:
- QString filename2(filename);
- QDir info(filename2);
- if (info.set
+ // QT solution:
+ QString filename2(filename);
+ QDir info(filename2);
+ if (info.set
struct utimbuf times;
times.actime = time_t(accessed.currentMSecsSinceEpoch() / 1000);
times.modtime = time_t(modified.currentMSecsSinceEpoch() / 1000);
* @return <code>true</code>: success
*/
bool ReFileUtils::setTimes(const QString& filename, const QDateTime& modified,
- const QDateTime& accessed, ReLogger* logger) {
- bool rc = true;
+ const QDateTime& accessed, ReLogger* logger) {
+ bool rc = true;
#if defined _WIN32
- // utime does not work with VS10-32-bit
- FILETIME accessed2 = unixTimeToFileTime(accessed.toMSecsSinceEpoch());
- FILETIME modified2 = unixTimeToFileTime(modified.toMSecsSinceEpoch());
- const ushort* name = filename.utf16();
+ // utime does not work with VS10-32-bit
+ FILETIME accessed2 = unixTimeToFileTime(accessed.toMSecsSinceEpoch());
+ FILETIME modified2 = unixTimeToFileTime(modified.toMSecsSinceEpoch());
+ const ushort* name = filename.utf16();
- HANDLE handle = CreateFileW(reinterpret_cast<const WCHAR*>(name), GENERIC_WRITE, FILE_SHARE_WRITE,
- NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
- if (handle == INVALID_HANDLE_VALUE){
- if (logger != NULL)
- logger->logv(LOG_ERROR, LOC_SET_TIMES_2,
- "cannot open file for time change (%d): %s", GetLastError(), filename);
- rc = false;
- } else if (! SetFileTime(handle, NULL, &accessed2, &modified2)){
- rc = false;
- if (logger != NULL)
- logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
- "cannot change times (%d): %s", errno, filename);
- CloseHandle(handle);
- }
+ HANDLE handle = CreateFileW(reinterpret_cast<const WCHAR*>(name), GENERIC_WRITE, FILE_SHARE_WRITE,
+ NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (handle == INVALID_HANDLE_VALUE){
+ if (logger != NULL)
+ logger->logv(LOG_ERROR, LOC_SET_TIMES_2,
+ "cannot open file for time change (%d): %s", GetLastError(), filename);
+ rc = false;
+ } else if (! SetFileTime(handle, NULL, &accessed2, &modified2)){
+ rc = false;
+ if (logger != NULL)
+ logger->logv(LOG_ERROR, LOC_SET_TIMES_1,
+ "cannot change times (%d): %s", errno, filename);
+ CloseHandle(handle);
+ }
#else
- rc = setTimes(I18N::s2b(filename).constData(), modified, accessed, logger);
+ rc = setTimes(I18N::s2b(filename).constData(), modified, accessed, logger);
#endif
- return rc;
+ return rc;
}
- bool rc = true;
+ bool rc = true;
/** Sets the read position of a file.
* @param file file to process
/**
* Converts the unix time (milliseconds from 1.1.1970) to the WIN32 filetime.
*
- * @param milliSecFromEpoche time as milliseconds from 1.1.1970
+ * @param milliSecFromEpoch time as milliseconds from 1.1.1970
* @return time as WIN32 filetime
*/
-FILETIME ReFileUtils::unixTimeToFileTime(qint64 milliSecFromEpoche)
+FILETIME ReFileUtils::unixTimeToFileTime(qint64 milliSecFromEpoch)
{
- FILETIME fileTime;
- // ll = Int32x32To64(t, 10000000) + 116444736000000000;
- LONGLONG value = milliSecFromEpoche * 10000LL + 116444736000000000LL;
- fileTime.dwLowDateTime = (DWORD) value;
- fileTime.dwHighDateTime = DWORD (value >> 32);
- return fileTime;
+ FILETIME fileTime;
+ // ll = Int32x32To64(t, 10000000) + 116444736000000000;
+ LONGLONG value = milliSecFromEpoch * 10000LL + 116444736000000000LL;
+ fileTime.dwLowDateTime = (DWORD) value;
+ fileTime.dwHighDateTime = DWORD (value >> 32);
+ return fileTime;
}
#endif
static QByteArray tempFile(const char* node, const char* parent = NULL,
bool deleteIfExists = true);
#if defined _WIN32
- static FILETIME unixTimeToFileTime(qint64 milliSecFromEpoche);
+ static FILETIME unixTimeToFileTime(qint64 milliSecFromEpoch);
#endif
static void writeToFile(const char* filename, const char* content,
size_t contentLength = (size_t) - 1, const char* mode = "w");
#include "base/rebase.hpp"
+enum {
+ LOC_Dummy_1 = LOC_FIRST_OF(LOC_PROCESS), // 12601
+};
+
ReProcess::ReProcess()
{
/**
* Executes an external program and return its output.
*
- * @param program the program to execute
- * @param args the program arguments
- * @param timeout the maximal count of seconds waiting for program's end
+ * @param program the program to execute
+ * @param args the program arguments
+ * @param timeout the maximal count of seconds waiting for program's end
+ * @param mergeStdErr <code>true</code>Output to stderr will be taken too
* @return the output (stdout) of the command
*/
QByteArray ReProcess::executeAndRead(const QString& program,
- const QStringList& args, int timeout)
+ const QStringList& args, int timeout, bool mergeStdError)
{
QProcess process;
+ if (mergeStdError)
+ process.setProcessChannelMode(QProcess::MergedChannels);
process.start(program, args, QIODevice::ReadOnly);
- process.waitForFinished(timeout * 1000);
+ process.waitForFinished();
QByteArray rc = process.readAllStandardOutput();
+ QString error = process.errorString();
return rc;
}
public:
static QByteArray executeAndRead(const QString& program,
- const QStringList& args, int timeout = 60);
+ 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);
LOC_CRYPTFILESYSTEM,
LOC_GUI_APPLICATION,
LOC_FILE_UTILS, // 125
+ LOC_PROCESS,
// Applications:
LOC_RECFORM_CPPPARSER = 201,
LOC_RECFORM_CPPFORMATTER = 202,
LOC_REIMGCONVERTER_ = 203,
LOC_REIMGCONVERTER_CONVERTER = 204,
+ LOC_REBACKGUI_BACKUPUTILS = 205,
};
#define LOC_FIRST_OF(moduleNo) (moduleNo*100+1)
class RplModules {