/*---------------------------------------------------------*\ | AutoStart-Linux.cpp | | | | Autostart implementation for Linux | | | | This file is part of the OpenRGB project | | SPDX-License-Identifier: GPL-2.0-or-later | \*---------------------------------------------------------*/ #include #include #include #include #include #include "AutoStart-Linux.h" #include "LogManager.h" #include "filesystem.h" AutoStart::AutoStart(std::string name) { InitAutoStart(name); } bool AutoStart::DisableAutoStart() { std::error_code autostart_file_remove_errcode; bool success = false; /*-----------------------------------------------------*\ | Check if the filename is valid | \*-----------------------------------------------------*/ if(autostart_file != "") { /*-------------------------------------------------*\ | If file doesn't exist, disable is successful | \*-------------------------------------------------*/ if(!filesystem::exists(autostart_file)) { success = true; } /*-------------------------------------------------*\ | Otherwise, delete the file | \*-------------------------------------------------*/ else { success = filesystem::remove(autostart_file, autostart_file_remove_errcode); if(!success) { LOG_ERROR("[AutoStart] An error occurred removing the auto start file."); } } } else { LOG_ERROR("[AutoStart] Could not establish correct autostart file path."); } return(success); } bool AutoStart::EnableAutoStart(AutoStartInfo autostart_info) { bool success = false; /*-----------------------------------------------------*\ | Check if the filename is valid | \*-----------------------------------------------------*/ if(autostart_file != "") { std::string desktop_file = GenerateDesktopFile(autostart_info); std::ofstream autostart_file_stream(autostart_file, std::ios::out | std::ios::trunc); /*-------------------------------------------------*\ | Error out if the file could not be opened | \*-------------------------------------------------*/ if(!autostart_file_stream) { LOG_ERROR("[AutoStart] Could not open %s for writing.", autostart_file.c_str()); success = false; } /*-------------------------------------------------*\ | Otherwise, write the file | \*-------------------------------------------------*/ else { autostart_file_stream << desktop_file; autostart_file_stream.close(); success = !autostart_file_stream.fail(); if (!success) { LOG_ERROR("[AutoStart] An error occurred writing the auto start file."); } } } else { LOG_ERROR("[AutoStart] Could not establish correct autostart file path."); } return(success); } bool AutoStart::IsAutoStartEnabled() { /*-----------------------------------------------------*\ | Check if the filename is valid | \*-----------------------------------------------------*/ if(autostart_file != "") { return(filesystem::exists(autostart_file)); } else { return(false); } } std::string AutoStart::GetExePath() { /*-----------------------------------------------------*\ | Create the OpenRGB executable path | \*-----------------------------------------------------*/ char exepath[ PATH_MAX ]; ssize_t count = readlink("/proc/self/exe", exepath, PATH_MAX); return(std::string(exepath, (count > 0) ? count : 0)); } /*---------------------------------------------------------*\ | Linux AutoStart Implementation | | Private Methods | \*---------------------------------------------------------*/ std::string AutoStart::GenerateDesktopFile(AutoStartInfo autostart_info) { /*-----------------------------------------------------*\ | Generate a .desktop file from the AutoStart | | parameters | \*-----------------------------------------------------*/ std::stringstream fileContents; fileContents << "[Desktop Entry]" << std::endl; fileContents << "Categories=" << autostart_info.category << std::endl; fileContents << "Comment=" << autostart_info.desc << std::endl; fileContents << "Icon=" << autostart_info.icon << std::endl; fileContents << "Name=" << GetAutoStartName() << std::endl; fileContents << "StartupNotify=true" << std::endl; fileContents << "Terminal=false" << std::endl; fileContents << "Type=Application" << std::endl; /*-----------------------------------------------------*\ | Add the executable path and arguments | \*-----------------------------------------------------*/ fileContents << "Exec=" << autostart_info.path; if (autostart_info.args != "") { fileContents << " " << autostart_info.args; } fileContents << std::endl; return(fileContents.str()); } void AutoStart::InitAutoStart(std::string name) { std::string autostart_dir; autostart_name = name; /*-----------------------------------------------------*\ | Get home and config paths | \*-----------------------------------------------------*/ const char *xdg_config_home = getenv("XDG_CONFIG_HOME"); const char *home = getenv("HOME"); /*-----------------------------------------------------*\ | Determine where the autostart .desktop files are | | kept | \*-----------------------------------------------------*/ if(xdg_config_home != NULL) { autostart_dir = xdg_config_home; autostart_dir = autostart_dir + "/autostart/"; } else if(home != NULL) { autostart_dir = home; autostart_dir = autostart_dir + "/.config/autostart/"; } /*-----------------------------------------------------*\ | Check if the filename is valid | \*-----------------------------------------------------*/ if(autostart_dir != "") { std::error_code ec; bool success = true; if(!filesystem::exists(autostart_dir)) { success = filesystem::create_directories(autostart_dir, ec); } if(success) { autostart_file = autostart_dir + autostart_name + ".desktop"; } } }