Check UNC path to avoid "hanging" if other machine is not reachable

This commit is contained in:
Klaus Basan
2020-04-14 02:44:02 +02:00
committed by Mat Sutcliffe
parent 04562a6651
commit e839820940
4 changed files with 93 additions and 2 deletions

View File

@@ -506,6 +506,31 @@ namespace BlackMisc
return f.left(i);
}
QSet<QString> CFileUtils::windowsUncMachines(const QSet<QString> &paths)
{
if (paths.isEmpty()) { return {}; }
const Qt::CaseSensitivity cs = osFileNameCaseSensitivity();
const bool isCs = isFileNameCaseSensitive();
QSet<QString> machines;
QString lastMachine;
for (const QString &p : paths)
{
if (!lastMachine.isEmpty() && p.contains(lastMachine, cs))
{
// shortcut
continue;
}
const QString m = isCs ? windowsUncMachine(p) : windowsUncMachine(p).toLower();
if (m.isEmpty()) { continue; }
lastMachine = m;
machines.insert(m);
}
return machines;
}
bool CFileUtils::canPingUncMachine(const QString &machine)
{
static QMap<QString, qint64> good;

View File

@@ -181,6 +181,9 @@ namespace BlackMisc
//! Machine in Windows UNC path
static QString windowsUncMachine(const QString &filePath);
//! All UNC machines from the paths
static QSet<QString> windowsUncMachines(const QSet<QString> &paths);
//! Can connect the UNC machine
static bool canPingUncMachine(const QString &machine);

View File

@@ -8,16 +8,18 @@
#include "blackmisc/simulation/aircraftmodellist.h"
#include "blackmisc/simulation/matchingutils.h"
#include "blackmisc/network/networkutils.h"
#include "blackmisc/aviation/callsign.h"
#include "blackmisc/aviation/logutils.h"
#include "blackmisc/math/mathutils.h"
#include "blackmisc/compare.h"
#include "blackmisc/iterator.h"
#include "blackmisc/range.h"
#include "fileutils.h"
#include "directoryutils.h"
#include "blackmisc/fileutils.h"
#include "blackmisc/directoryutils.h"
#include "blackmisc/statusmessage.h"
#include "blackmisc/stringutils.h"
#include "blackconfig/buildconfig.h"
#include <QStringBuilder>
#include <QJsonValue>
@@ -27,6 +29,7 @@
#include <QDir>
#include <tuple>
using namespace BlackConfig;
using namespace BlackMisc::Network;
using namespace BlackMisc::Math;
using namespace BlackMisc::Aviation;
@@ -1352,6 +1355,22 @@ namespace BlackMisc
return files;
}
QSet<QString> CAircraftModelList::getAllUNCFileNames() const
{
const bool cs = CFileUtils::isFileNameCaseSensitive();
QSet<QString> files;
for (const CAircraftModel &model : as_const(*this))
{
if (!model.hasFileName()) { continue; }
const QString fn = (cs ? model.getFileName() : model.getFileNameLowerCase());
if (CFileUtils::isWindowsUncPath(fn))
{
files.insert(fn);
}
}
return files;
}
QString CAircraftModelList::getCombinedTypesAsString(const QString &separator) const
{
if (this->isEmpty()) { return {}; }
@@ -1540,6 +1559,13 @@ namespace BlackMisc
CAircraftModelList sorted(*this);
if (!alreadySortedByFn) { sorted.sortByFileName(); }
// avoid hanging if UNC paths are not available
if (CBuildConfig::isRunningOnWindowsNtPlatform())
{
const CStatusMessageList uncMsgs = this->validateUncFiles(sorted.getAllUNCFileNames());
if (uncMsgs.hasErrorMessages()) { return uncMsgs; }
}
const bool caseSensitive = CFileUtils::isFileNameCaseSensitive();
const QString simRootDir = CFileUtils::normalizeFilePathToQtStandard(
CFileUtils::stripLeadingSlashOrDriveLetter(
@@ -1615,6 +1641,35 @@ namespace BlackMisc
return msgs;
}
CStatusMessageList CAircraftModelList::validateUncFiles(const QSet<QString> uncFiles) const
{
// check if UNC paths can be reached
CStatusMessageList msgs;
if (!CBuildConfig::isRunningOnWindowsNtPlatform()) { return msgs; }
if (uncFiles.isEmpty()) { return msgs; }
const QSet<QString> uncMachines = CFileUtils::windowsUncMachines(uncFiles);
if (uncMachines.isEmpty())
{
msgs.push_back(CStatusMessage(this).validationInfo(u"Found NO UNC machines for %1 files, odd...?") << uncFiles.size());
}
else
{
const QString machines = joinStringSet(uncMachines, ", ");
msgs.push_back(CStatusMessage(this).validationInfo(u"Found %1 UNC files on machines: %2") << uncFiles.size() << machines);
}
for (const QString &m : uncMachines)
{
const bool ping = CNetworkUtils::canPing(m);
if (!ping)
{
msgs.push_back(CStatusMessage(this).validationError(u"Cannot ping UNC machine(s): %1. UNC files: %2") << m << uncFiles.size());
}
}
return msgs;
}
QJsonObject CAircraftModelList::toMemoizedJson() const
{
CAircraftModel::MemoHelper::CMemoizer helper;

View File

@@ -473,6 +473,10 @@ namespace BlackMisc
//! All file names
QSet<QString> getAllFileNames() const;
//! All UNC file names
//! \remark Windows on a "shared drive" paths
QSet<QString> getAllUNCFileNames() const;
//! All combined types as string
QString getCombinedTypesAsString(const QString &separator = ", ") const;
@@ -555,6 +559,10 @@ namespace BlackMisc
const Aviation::CAircraftCategoryList &aircraftCategories = {},
const Aviation::CLiveryList &liveries = {},
const CDistributorList &distributors = {});
private:
//! Validate UNC paths (Windows)
CStatusMessageList validateUncFiles(const QSet<QString> uncFiles) const;
};
//! Model per callsign