diff --git a/src/modules/users/Config.cpp b/src/modules/users/Config.cpp index ac01f9933..9deaef81f 100644 --- a/src/modules/users/Config.cpp +++ b/src/modules/users/Config.cpp @@ -26,6 +26,7 @@ #include "utils/String.h" #include "utils/Variant.h" +#include #include Config::Config( QObject* parent ) @@ -84,12 +85,56 @@ Config::setLoginName( const QString& login ) } } -static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" ); +void +Config::setHostName( const QString& host ) +{ + if ( host != m_hostName ) + { + m_customHostName = !host.isEmpty(); + m_hostName = host; + emit hostNameChanged( host ); + } +} + + +/** @brief Guess the machine's name + * + * If there is DMI data, use that; otherwise, just call the machine "-pc". + * Reads the DMI data just once. + */ +static QString +guessProductName() +{ + static bool tried = false; + static QString dmiProduct; + + if ( !tried ) + { + // yes validateHostnameText() but these files can be a mess + QRegExp dmirx( "[^a-zA-Z0-9]", Qt::CaseInsensitive ); + QFile dmiFile( QStringLiteral( "/sys/devices/virtual/dmi/id/product_name" ) ); + + if ( dmiFile.exists() && dmiFile.open( QIODevice::ReadOnly ) ) + { + dmiProduct = QString::fromLocal8Bit( dmiFile.readAll().simplified().data() ) + .toLower() + .replace( dmirx, " " ) + .remove( ' ' ); + } + if ( dmiProduct.isEmpty() ) + { + dmiProduct = QStringLiteral( "-pc" ); + } + tried = true; + } + return dmiProduct; +} static QString makeLoginNameSuggestion( const QStringList& parts ) { - if ( parts.isEmpty() ) + static const QRegExp USERNAME_RX( "^[a-z_][a-z0-9_-]*[$]?$" ); + if ( parts.isEmpty() || parts.first().isEmpty() ) { return QString(); } @@ -106,6 +151,20 @@ makeLoginNameSuggestion( const QStringList& parts ) return USERNAME_RX.indexIn( usernameSuggestion ) != -1 ? usernameSuggestion : QString(); } +static QString +makeHostnameSuggestion( const QStringList& parts ) +{ + static const QRegExp HOSTNAME_RX( "^[a-zA-Z0-9][-a-zA-Z0-9_]*$" ); + if ( parts.isEmpty() || parts.first().isEmpty() ) + { + return QString(); + } + + QString productName = guessProductName(); + QString hostnameSuggestion = QStringLiteral( "%1-%2" ).arg( parts.first() ).arg( productName ); + return HOSTNAME_RX.indexIn( hostnameSuggestion ) != -1 ? hostnameSuggestion : QString(); +} + void Config::setUserName( const QString& name ) { @@ -128,10 +187,18 @@ Config::setUserName( const QString& name ) emit loginNameChanged( login ); } } + if ( !m_customHostName ) + { + QString hostname = makeHostnameSuggestion( cleanParts ); + if ( !hostname.isEmpty() && hostname != m_hostName ) + { + m_hostName = hostname; + emit hostNameChanged( hostname ); + } + } } } - void Config::setConfigurationMap( const QVariantMap& configurationMap ) { diff --git a/src/modules/users/Config.h b/src/modules/users/Config.h index 6aed5840f..59f0e8d68 100644 --- a/src/modules/users/Config.h +++ b/src/modules/users/Config.h @@ -36,6 +36,8 @@ class Config : public QObject Q_PROPERTY( QString userName READ userName WRITE setUserName NOTIFY userNameChanged ) Q_PROPERTY( QString loginName READ loginName WRITE setLoginName NOTIFY loginNameChanged ) + Q_PROPERTY( QString hostName READ hostName WRITE setHostName NOTIFY hostNameChanged ) + public: Config( QObject* parent = nullptr ); ~Config(); @@ -59,6 +61,9 @@ public: /// The login name of the user QString loginName() const { return m_loginName; } + /// The host name (name for the system) + QString hostName() const { return m_hostName; } + public Q_SLOTS: /** @brief Sets the user's shell if possible * @@ -80,12 +85,16 @@ public Q_SLOTS: /// Sets the login name (flags it as "custom") void setLoginName( const QString& login ); + /// Sets the host name (flags it as "custom") + void setHostName( const QString& host ); + signals: void userShellChanged( const QString& ); void autologinGroupChanged( const QString& ); void sudoersGroupChanged( const QString& ); void userNameChanged( const QString& ); void loginNameChanged( const QString& ); + void hostNameChanged( const QString& ); private: QString m_userShell; @@ -93,7 +102,9 @@ private: QString m_sudoersGroup; QString m_fullName; QString m_loginName; + QString m_hostName; bool m_customLoginName = false; + bool m_customHostName = false; }; #endif