diff --git a/src/private/standarddirs.cpp b/src/private/standarddirs.cpp --- a/src/private/standarddirs.cpp +++ b/src/private/standarddirs.cpp @@ -110,6 +110,8 @@ fullPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + fullRelPath; } else if (qstrncmp(resource, "data", 4) == 0) { fullPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + fullRelPath; + } else if (qstrncmp(resource, "runtime", 7) == 0) { + fullPath = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation) + fullRelPath; } else { qt_assert_x(__FUNCTION__, "Invalid resource type", __FILE__, __LINE__); return {}; diff --git a/src/server/utils.cpp b/src/server/utils.cpp --- a/src/server/utils.cpp +++ b/src/server/utils.cpp @@ -21,6 +21,7 @@ #include "utils.h" #include "akonadiserver_debug.h" +#include "instance_p.h" #include @@ -32,13 +33,13 @@ #if !defined(Q_OS_WIN) #include #include +#include #include -#include #include static QString akonadiSocketDirectory(); static bool checkSocketDirectory(const QString &path); -static bool createSocketDirectory(const QString &link, const QString &tmpl); +static bool createSocketDirectory(const QString &link, const QString &identifier); #endif #ifdef Q_OS_LINUX @@ -67,6 +68,11 @@ if (socketDir.isEmpty()) { // if that does not work, fall back on default socketDir = defaultDirectory; } + + if (socketDir.length() > static_cast(sizeof(sockaddr_un::sun_path))) { + qCWarning(AKONADISERVER_LOG) << "akonadiSocketDirectory() length is too long to be used by the system, fallbacking to the default directory."; + socketDir = defaultDirectory; + } } else { socketDir = serverSettings.value(QStringLiteral("Connection/SocketDirectory"), defaultDirectory).toString(); } @@ -101,25 +107,14 @@ return QString(); } - const uid_t uid = getuid(); - const struct passwd *pw_ent = getpwuid(uid); - if (!pw_ent) { - qCCritical(AKONADISERVER_LOG) << "Could not get passwd entry for user id" << uid; - return QString(); - } - - const QString link = StandardDirs::saveDir("data") + QLatin1Char('/') + QLatin1String("socket-") + hostname; - QString tmpl = QLatin1String("akonadi-") + QString::fromLocal8Bit(pw_ent->pw_name) + QLatin1String(".XXXXXX"); - - // Workaround for QLocalServer encoding bug - // basically replace non-latin characters - tmpl = QString::fromLatin1(tmpl.toLatin1()); + const QString identifier = Instance::hasIdentifier() ? Instance::identifier() : QLatin1String("default"); + const QString link = StandardDirs::saveDir("data") + QDir::separator() + QStringLiteral("socket-%1-%2").arg(hostname, identifier); if (checkSocketDirectory(link)) { return QFileInfo(link).symLinkTarget(); } - if (createSocketDirectory(link, tmpl)) { + if (createSocketDirectory(link, identifier)) { return QFileInfo(link).symLinkTarget(); } @@ -150,19 +145,15 @@ return true; } -static bool createSocketDirectory(const QString &link, const QString &tmpl) +static bool createSocketDirectory(const QString &link, const QString &identifier) { - QString directory = QStringLiteral("%1%2%3").arg(QDir::tempPath()).arg(QDir::separator()).arg(tmpl); + const QString directory = QStringLiteral("%1%3%2").arg(StandardDirs::saveDir("runtime"), identifier).arg(QDir::separator()); - QByteArray directoryString = directory.toLocal8Bit(); - - if (!mkdtemp(directoryString.data())) { - qCCritical(AKONADISERVER_LOG) << "Creating socket directory with template" << directoryString << "failed:" << strerror(errno); + if (!QDir().mkpath(directory)) { + qCCritical(AKONADISERVER_LOG) << "Creating socket directory with name" << directory << "failed:" << strerror(errno); return false; } - directory = QString::fromLocal8Bit(directoryString); - QFile::remove(link); if (!QFile::link(directory, link)) { @@ -177,6 +168,7 @@ QString Utils::getDirectoryFileSystem(const QString &directory) { #ifndef Q_OS_LINUX + Q_UNUSED(directory); return QString(); #else QString bestMatchPath;