diff --git a/CMakeLists.txt b/CMakeLists.txt index 28e8055..87f8f32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,90 +1,96 @@ cmake_minimum_required(VERSION 3.0) project(kwrited) set(PROJECT_VERSION "5.13.80") set(QT_MIN_VERSION "5.9.0") set(KF5_MIN_VERSION "5.42.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) include(CMakeDependentOption) include(KDEInstallDirs) include(KDECMakeSettings) include(KDECompilerSettings NO_POLICY_SCOPE) include(FeatureSummary) find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS Widgets ) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS CoreAddons I18n Pty Notifications ) cmake_dependent_option(BUILD_AS_EXECUTABLE "Whether to build kwrited as executable" OFF "KPty_HAVE_UTEMPTER" ON) if (NOT BUILD_AS_EXECUTABLE) find_package(KF5DBusAddons ${KF5_MIN_VERSION}) set_package_properties(KF5DBusAddons PROPERTIES DESCRIPTION "Convenience classes for DBus" TYPE REQUIRED PURPOSE "Needed to build kwrited's KDED module" ) endif () +add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") +add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) +#add_definitions(-DQT_DISABLE_DEPRECATED_BEFORE=0x050a00) +add_definitions(-DQT_NO_URL_CAST_FROM_STRING) +add_definitions(-DQT_USE_QSTRINGBUILDER) + # If libutempter is not available on the system, we build # kwrited as an executable that is installed with setuid root # (or setgid utmp) in order to be able to login successfully # (and thus be useful, as kwrited does not work at all if it # cannot login to the terminal device that it opens). configure_file(config-kwrited.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kwrited.h) if (BUILD_AS_EXECUTABLE) add_executable(kwrited kwrited.cpp) target_compile_definitions(kwrited PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") target_link_libraries(kwrited Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::Notifications KF5::Pty) install(TARGETS kwrited ${INSTALL_TARGETS_DEFAULT_ARGS} ) if(IS_ABSOLUTE BIN_INSTALL_DIR) set(ABS_BIN_INSTALL_DIR "${BIN_INSTALL_DIR}") else() set(ABS_BIN_INSTALL_DIR "\${CMAKE_INSTALL_PREFIX}/${BIN_INSTALL_DIR}") endif() install(CODE " set(KWRITED_PATH \"\$ENV{DESTDIR}${ABS_BIN_INSTALL_DIR}/kwrited\") # On Debian we setgid instead of setuid. # Feel free to add checks here for other distros as well, if needed. if (EXISTS /etc/debian_version) set(SETGID 1) set(SETGID_GROUP utmp) endif () if (SETGID) execute_process(COMMAND sh -c \"chgrp \${SETGID_GROUP} '\${KWRITED_PATH}' && chmod g+s '\${KWRITED_PATH}'\") else () execute_process(COMMAND sh -c \"chown root '\${KWRITED_PATH}' && chmod u+s '\${KWRITED_PATH}'\") endif() ") install(FILES kwrited-autostart.desktop DESTINATION ${AUTOSTART_INSTALL_DIR}) else () kcoreaddons_add_plugin(kded_kwrited SOURCES kwrited.cpp JSON kwrited.json INSTALL_NAMESPACE "kf5/kded" ) set_target_properties(kded_kwrited PROPERTIES OUTPUT_NAME kwrited) target_compile_definitions(kded_kwrited PRIVATE -DPROJECT_VERSION="${PROJECT_VERSION}") target_link_libraries(kded_kwrited KF5::CoreAddons KF5::DBusAddons KF5::I18n KF5::Notifications KF5::Pty) endif () # The .notifyrc file is common install(FILES kwrited.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/kwrited.cpp b/kwrited.cpp index 1df1f2c..3386e00 100644 --- a/kwrited.cpp +++ b/kwrited.cpp @@ -1,169 +1,169 @@ /* kwrited is a write(1) receiver for KDE. Copyright 1997,1998 by Lars Doelle Copyright 2008 by George Kiagiadakis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ // Own #include "kwrited.h" #include #include #include #include #include #include #if defined(BUILD_AS_EXECUTABLE) # include # include # include # include # include #else # include # include #endif static inline KAboutData aboutData() { - return KAboutData("kwrited", i18n("kwrited"), PROJECT_VERSION); + return KAboutData(QStringLiteral("kwrited"), i18n("kwrited"), QLatin1String(PROJECT_VERSION)); } #if defined(BUILD_AS_EXECUTABLE) static uid_t original_euid; static gid_t original_egid; static void sigterm_handler(int signal) { Q_UNUSED(signal) QApplication::quit(); } int main(int argc, char **argv) { //drop elevated privileges temporarily original_euid = geteuid(); original_egid = getegid(); seteuid(getuid()); setegid(getgid()); //install a signal handler to exit gracefully //(so that pty->logout() is called in ~KWrited()) signal(SIGTERM, sigterm_handler); signal(SIGINT, sigterm_handler); signal(SIGHUP, sigterm_handler); QApplication::setDesktopSettingsAware(false); QApplication a(argc, argv); KAboutData::setApplicationData(aboutData()); QGuiApplication::setFallbackSessionManagementEnabled(false); auto disableSessionManagement = [](QSessionManager &sm) { sm.setRestartHint(QSessionManager::RestartNever); }; QObject::connect(&a, &QGuiApplication::commitDataRequest, disableSessionManagement); QObject::connect(&a, &QGuiApplication::saveStateRequest, disableSessionManagement); KWrited w; return a.exec(); } #else // BUILD_AS_EXECUTABLE KWritedModule::KWritedModule(QObject* parent, const QList&) : KDEDModule(parent) { pro = new KWrited; } KWritedModule::~KWritedModule() { delete pro; } K_PLUGIN_FACTORY_WITH_JSON(KWritedFactory, "kwrited.json", registerPlugin(); ) #endif //BUILD_AS_EXECUTABLE KWrited::KWrited() : QObject() { pty = new KPtyDevice(); pty->open(); #if defined(BUILD_AS_EXECUTABLE) dup2(pty->slaveFd(), 0); //HACK: login() from glibc requires this to login correctly //restore elevated privileges seteuid(original_euid); setegid(original_egid); #endif pty->login(KUser(KUser::UseRealUserID).loginName().toLocal8Bit().data(), qgetenv("DISPLAY")); #if defined(BUILD_AS_EXECUTABLE) //drop privileges again seteuid(getuid()); setegid(getgid()); #endif connect(pty, SIGNAL(readyRead()), this, SLOT(block_in())); //qDebug() << "listening on device" << pty->ttyName(); } KWrited::~KWrited() { #if defined(BUILD_AS_EXECUTABLE) //restore elevated privileges seteuid(original_euid); setegid(original_egid); #endif pty->logout(); #if defined(BUILD_AS_EXECUTABLE) //drop privileges again seteuid(getuid()); setegid(getgid()); #endif delete pty; } void KWrited::block_in() { QByteArray buf = pty->readAll(); QString msg = QString::fromLocal8Bit( buf.constData(), buf.size() ); - msg.remove('\r'); - msg.remove('\a'); + msg.remove(QLatin1Char('\r')); + msg.remove(QLatin1Char('\a')); - KNotification *notification = new KNotification("NewMessage", nullptr, KNotification::Persistent); + KNotification *notification = new KNotification(QStringLiteral("NewMessage"), nullptr, KNotification::Persistent); #if !defined(BUILD_AS_EXECUTABLE) notification->setComponentName( QStringLiteral("kwrited") ); #endif notification->setText( msg ); connect(notification, SIGNAL(closed()), notification, SLOT(deleteLater()) ); notification->sendEvent(); } #if !defined(BUILD_AS_EXECUTABLE) #include "kwrited.moc" #endif