318 lines
12 KiB
C++
Executable File
318 lines
12 KiB
C++
Executable File
//-----------------------------------------------------------------------------------------//
|
|
// Distributed under the MIT License - https://opensource.org/licenses/MIT
|
|
//-----------------------------------------------------------------------------------------//
|
|
//
|
|
// Copyright © 2019 Sasko Usinov
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// in the Software without restriction, including without limitation the rights to
|
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
|
// subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in all
|
|
// copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
|
|
// OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
//-----------------------------------------------------------------------------------------//
|
|
// Distributed under the MIT License - https://opensource.org/licenses/MIT
|
|
//-----------------------------------------------------------------------------------------//
|
|
|
|
#define QT_NO_KEYWORDS
|
|
|
|
#include "api.h"
|
|
#include "liblogman/log_manager.h"
|
|
|
|
#include <iostream>
|
|
#include <string>
|
|
#include <sstream>
|
|
|
|
#include <sys/klog.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sstream>
|
|
#include <fstream>
|
|
#include <algorithm>
|
|
|
|
#include <limits.h>
|
|
#include <gio/gio.h>
|
|
|
|
api::log_manager api::sys::g_out, api::sys::g_err(api::log_manager::level_err);
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Obtains the canonical absolute name of path
|
|
//
|
|
// Returns: The absolute path to the file or blank if it fails to resolve it
|
|
//
|
|
//------------------------------------------------------------------------------//
|
|
std::string api::sys::read_link(const std::string & path)
|
|
{
|
|
char buff[PATH_MAX];
|
|
char * res = realpath(path.c_str(), buff);
|
|
|
|
return (res) ? std::string(res) : std::string();
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: method
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Requires:
|
|
// #include <gio/gio.h>
|
|
//
|
|
// Compile with:
|
|
// -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fpermissive -lgio-2.0
|
|
//
|
|
// If using with Qt, put #define QT_NO_KEYWORDS at the top of the file
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
std::string api::sys::get_file_icon_name(const std::string & file_path)
|
|
{
|
|
// typedef std::vector<std::string> string_list;
|
|
|
|
if (!api::fs::path_exists(file_path))
|
|
return std::string();
|
|
|
|
std::string home_dir {get_env("HOME")};
|
|
GError * error;
|
|
GFile * file = g_file_new_for_path (file_path.c_str());
|
|
GFileInfo * file_info = g_file_query_info (file, "standard::*", GFileQueryInfoFlags::G_FILE_QUERY_INFO_NONE, nullptr, &error);
|
|
|
|
// const char * content_type = g_file_info_get_content_type (file_info);
|
|
// char * desc = g_content_type_get_description (content_type);
|
|
// GAppInfo * app_info = g_app_info_get_default_for_type (content_type, FALSE);
|
|
|
|
GIcon * icon = g_file_info_get_icon (file_info);
|
|
const char * file_icon = g_icon_to_string (icon);
|
|
|
|
// log "g_icon_to_string returned: \"" << file_icon << "\"";
|
|
// log "Content Type is: \"" << content_type << "\"";
|
|
// log "Description is: \"" << desc << "\"";
|
|
|
|
return file_icon;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// Type: method
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Requires:
|
|
// #include <gio/gio.h>
|
|
//
|
|
// Compile with:
|
|
// -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fpermissive -lgio-2.0
|
|
//
|
|
// If using with Qt, put #define QT_NO_KEYWORDS at the top of the file
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//
|
|
// SPECIAL NOTE: This function is extremely, extremely slow and unefficient.
|
|
// Use it for single files only, not multiple files (it's slow)
|
|
//
|
|
//-------------------------------------------------------------------------------//
|
|
std::string api::sys::get_file_icon_path(const std::string & file_path, const std::vector<std::string> & icon_theme_paths, const std::string & icon_theme_name, const std::string & icon_label)
|
|
{
|
|
if (!api::fs::path_exists(file_path))
|
|
return std::string();
|
|
|
|
GError * error;
|
|
GFile * file = g_file_new_for_path (file_path.c_str());
|
|
GFileInfo * file_info = g_file_query_info (file, "standard::*", GFileQueryInfoFlags::G_FILE_QUERY_INFO_NONE, nullptr, &error);
|
|
|
|
// const char * content_type = g_file_info_get_content_type (file_info);
|
|
// char * desc = g_content_type_get_description (content_type);
|
|
// GAppInfo * app_info = g_app_info_get_default_for_type (content_type, FALSE);
|
|
|
|
GIcon * icon = g_file_info_get_icon (file_info);
|
|
const char * file_icon_name = g_icon_to_string (icon);
|
|
|
|
std::string icon_path {};
|
|
std::vector<std::string> icon_names_list {icon_label.empty() ? api::vct::to_vector_string_list(file_icon_name, 32) : std::vector<std::string> () = {icon_label}};
|
|
std::string trimmed_name {};
|
|
|
|
// log "(): g_icon_to_string returned: \"" << file_icon_name << "\"";
|
|
// log "(): Content Type is: \"" << content_type << "\"";
|
|
// log "(): Description is: \"" << desc << "\"";
|
|
|
|
for (size_t i = 0; i < icon_theme_paths.size(); i++)
|
|
{
|
|
if (icon_theme_paths[i][0] == ':') continue;
|
|
|
|
if (api::fs::path_exists(icon_theme_paths[i] + "/" + icon_theme_name))
|
|
{
|
|
for (size_t x = 0; x < icon_names_list.size(); x++)
|
|
{
|
|
trimmed_name = api::str::trim(icon_names_list[x]);
|
|
|
|
if (trimmed_name == ".") continue;
|
|
|
|
std::string icon_locate_command {"find " + icon_theme_paths[i] + "/" + icon_theme_name + " -name " + "\"" + trimmed_name + "*\""};
|
|
std::vector<std::string> paths {api::vct::to_vector_string_list(api::cns::run(icon_locate_command), std::vector<char> () = {10, 13})};
|
|
|
|
if (paths.size() > 1)
|
|
{
|
|
icon_path = api::str::trim(paths[paths.size() - 2]);
|
|
goto exit_op;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// We failed to find the icon in the specified theme name
|
|
//-------------------------------------------------------------------------------//
|
|
if (!icon_path.size())
|
|
{
|
|
// log "DID NOT find icon in " + icon_theme_name + ". Searching other themes..." << icon_path;
|
|
|
|
for (size_t i = 0; i < icon_theme_paths.size(); i++)
|
|
{
|
|
if (icon_theme_paths[i][0] == ':') continue;
|
|
|
|
for (size_t x = 0; x < icon_names_list.size(); x++)
|
|
{
|
|
trimmed_name = api::str::trim(icon_names_list[x]);
|
|
|
|
if (trimmed_name == ".") continue;
|
|
|
|
std::string icon_locate_command {"find " + icon_theme_paths[i] + " -name " + "\"" + api::str::trim(icon_names_list[x]) + "*\""};
|
|
std::vector<std::string> paths {api::vct::to_vector_string_list(api::cns::run(icon_locate_command), std::vector<char> () = {10, 13})};
|
|
|
|
if (paths.size() > 1)
|
|
{
|
|
icon_path = api::str::trim(paths[paths.size() - 2]);
|
|
goto exit_op;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
exit_op:
|
|
{
|
|
// log "Exiting, calculated icon path is: " << icon_path;
|
|
return icon_path;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Tries to return the library loaded search paths
|
|
//
|
|
// $ ldconfig -v 2> /dev/null | grep -v ^$'\t'
|
|
//
|
|
// /usr/lib/x86_64-linux-gnu/libfakeroot:
|
|
// /lib/i386-linux-gnu:
|
|
// /usr/local/lib:
|
|
// /lib/x86_64-linux-gnu:
|
|
// /lib32:
|
|
// /libx32:
|
|
// /lib:
|
|
// /lib/i386-linux-gnu/i686: (hwcap: 0x0002000000000000)
|
|
// /lib/i386-linux-gnu/sse2: (hwcap: 0x0000000000000001)
|
|
// /lib/i386-linux-gnu/i686/sse2: (hwcap: 0x0002000000000001)
|
|
//
|
|
// Returns: A vector of strings where each item is a separate path
|
|
//
|
|
//------------------------------------------------------------------------------//
|
|
std::vector<std::string> api::sys::get_library_loader_search_paths()
|
|
{
|
|
std::vector<std::string> tmp_list = api::vct::to_vector_string_list(api::cns::exec("ldconfig -v 2> /dev/null | grep -v ^$'\t'", "/tmp").std_out, 10, 13);
|
|
|
|
std::vector<std::string> out;
|
|
|
|
for (size_t i = 0; i < tmp_list.size(); i++)
|
|
{
|
|
if (!api::str::trim(tmp_list[i]).size())
|
|
continue;
|
|
|
|
size_t path_end = api::str::get_char_index(':', 1, tmp_list[i]);
|
|
|
|
if (path_end == API_ERROR_IDX_NOT_FOUND)
|
|
path_end = tmp_list[i].size();
|
|
|
|
out.push_back(api::str::trim(api::str::range_copy(0, path_end - 1, tmp_list[i])));
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
//-------------------------------------------------------------------------------//
|
|
// namespace
|
|
//-------------------------------------------------------------------------------//
|
|
//
|
|
// ToDo: n/a
|
|
//
|
|
// Notes: Runs a command in the background
|
|
//
|
|
// I am almost certain someone will hate what this code is doing
|
|
// but the reason I am doing it is because I am having issues
|
|
// launching Qt applications from my own Qt program because the runtime loads
|
|
// the wrong Qt shared libs. A perfect example of this is vlc
|
|
//
|
|
// If you do system("vlc -v &") from within my Qt applicarion or even if you
|
|
// use QProcess(), vlc won't start because ld.so loads incorrect Qt libs
|
|
// and the runtime complains about incorrect Qt versions
|
|
//
|
|
// So this is my workaround, love it, hate it, it does seem to work (around)...
|
|
//
|
|
//
|
|
// Returns: n/a
|
|
//
|
|
//------------------------------------------------------------------------------//
|
|
void api::sys::exec_background_cmd(const std::string & cmd, bool run_as_root)
|
|
{
|
|
std::string script_path {api::fs::generate_unique_filename("/tmp", "tmp-cmd")};
|
|
std::vector<std::string> script;
|
|
|
|
run_as_root ? script.push_back("#!/usr/bin/pkexec /bin/bash") : script.push_back("#!/bin/bash");
|
|
|
|
script.push_back("unset LD_LIBRARY_PATH");
|
|
script.push_back("unset QT_PLUGIN_PATH");
|
|
script.push_back("unset QT_QPA_PLATFORM_PLUGIN_PATH");
|
|
|
|
script.push_back(cmd);
|
|
|
|
if (!api::fs::save_to_file(script_path, api::vct::to_string(script, '\n')))
|
|
{
|
|
std::cerr << ": Failed at saving file: " + script_path;
|
|
return;
|
|
}
|
|
|
|
if (system(("chmod u+x " + script_path).c_str()))
|
|
{
|
|
std::cerr << ": Failed at chmoding file: " + script_path;
|
|
return;
|
|
}
|
|
|
|
std::cout << "Runnng: " << script_path;
|
|
|
|
std::system((script_path + " &" ).c_str());
|
|
}
|