1
0
mirror of synced 2024-11-28 01:20:51 +01:00

sys: Log to a file when ImHex wasn't opened though a terminal

This commit is contained in:
WerWolv 2022-01-17 20:06:00 +01:00
parent 2df4e22bf8
commit 8701e0f402
15 changed files with 155 additions and 42 deletions

7
.idea/vcs.xml generated
View File

@ -9,5 +9,12 @@
<mapping directory="$PROJECT_DIR$/external/nativefiledialog" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/xdgpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/external/yara/yara" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/capstone" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/curl" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/fmt" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/libromfs" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/nativefiledialog" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/xdgpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/external/yara/yara" vcs="Git" />
</component>
</project>

View File

@ -123,6 +123,7 @@ set(LIBIMHEX_SOURCES
source/helpers/project_file_handler.cpp
source/helpers/encoding_file.cpp
source/helpers/loader_script_handler.cpp
source/helpers/logger.cpp
source/pattern_language/pattern_language.cpp
source/pattern_language/preprocessor.cpp

View File

@ -26,13 +26,16 @@ namespace hex {
Create
};
explicit File(const fs::path &path, Mode mode);
File();
explicit File(const fs::path &path, Mode mode) noexcept;
File() noexcept;
File(const File&) = delete;
File(File &&other) noexcept;
~File();
File& operator=(File &&other) noexcept;
[[nodiscard]] bool isValid() const { return this->m_file != nullptr; }
void seek(u64 offset);

View File

@ -5,36 +5,54 @@
namespace hex::log {
FILE *getDestination();
bool isRedirected();
template <typename... T>
void print(fmt::format_string<T...> fmt, T&&... args) {
fmt::print(getDestination(), fmt, args...);
}
template <typename S, typename... Args>
void print(const fmt::text_style& ts, const S& fmt, const Args&... args) {
if (isRedirected())
fmt::print(getDestination(), fmt::runtime(fmt), args...);
else
fmt::print(getDestination(), ts, fmt, args...);
}
void debug(const std::string &fmt, auto ... args) {
#if defined(DEBUG)
fmt::print(fg(fmt::color::green_yellow) | fmt::emphasis::bold, "[DEBUG] ");
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
log::print(fg(fmt::color::green_yellow) | fmt::emphasis::bold, "[DEBUG] ");
log::print(fmt::runtime(fmt), args...);
log::print("\n");
#endif
}
void info(const std::string &fmt, auto ... args) {
fmt::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ");
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
log::print(fg(fmt::color::cadet_blue) | fmt::emphasis::bold, "[INFO] ");
log::print(fmt::runtime(fmt), args...);
log::print("\n");
}
void warn(const std::string &fmt, auto ... args) {
fmt::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ");
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
log::print(fg(fmt::color::orange) | fmt::emphasis::bold, "[WARN] ");
log::print(fmt::runtime(fmt), args...);
log::print("\n");
}
void error(const std::string &fmt, auto ... args) {
fmt::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR] ");
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
log::print(fg(fmt::color::red) | fmt::emphasis::bold, "[ERROR] ");
log::print(fmt::runtime(fmt), args...);
log::print("\n");
}
void fatal(const std::string &fmt, auto ... args) {
fmt::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL] ");
fmt::print(fmt::runtime(fmt), args...);
fmt::print("\n");
log::print(fg(fmt::color::purple) | fmt::emphasis::bold, "[FATAL] ");
log::print(fmt::runtime(fmt), args...);
log::print("\n");
}
void redirectToFile();
}

View File

@ -17,7 +17,8 @@ namespace hex {
Yara,
Config,
Resources,
Constants
Constants,
Logs
};
std::string getExecutablePath();

View File

@ -3,7 +3,7 @@
namespace hex {
File::File(const fs::path &path, Mode mode) : m_path(path) {
File::File(const fs::path &path, Mode mode) noexcept : m_path(path) {
if (mode == File::Mode::Read)
this->m_file = fopen64(path.string().c_str(), "rb");
else if (mode == File::Mode::Write)
@ -13,7 +13,7 @@ namespace hex {
this->m_file = fopen64(path.string().c_str(), "w+b");
}
File::File() {
File::File() noexcept {
this->m_file = nullptr;
}
@ -26,6 +26,16 @@ namespace hex {
this->close();
}
File& File::operator=(File &&other) noexcept {
this->m_file = other.m_file;
other.m_file = nullptr;
this->m_path = std::move(other.m_path);
return *this;
}
void File::seek(u64 offset) {
fseeko64(this->m_file, offset, SEEK_SET);
}

View File

@ -0,0 +1,33 @@
#include <hex/helpers/logger.hpp>
#include <hex/helpers/file.hpp>
#include <hex/helpers/paths.hpp>
#include <hex/helpers/fmt.hpp>
#include <iostream>
namespace hex::log {
static File g_loggerFile;
FILE* getDestination() {
if (g_loggerFile.isValid())
return g_loggerFile.getHandle();
else
return stdout;
}
bool isRedirected() {
return g_loggerFile.isValid();
}
void redirectToFile() {
if (g_loggerFile.isValid()) return;
for (const auto &path : hex::getPath(ImHexPath::Logs)) {
g_loggerFile = File(path / hex::format("{0:%Y%m%d_%H%M%S}.log", fmt::localtime(std::chrono::system_clock::now())), File::Mode::Create);
if (g_loggerFile.isValid()) break;
}
}
}

View File

@ -98,6 +98,11 @@ namespace hex {
return (path / "constants").string();
});
break;
case ImHexPath::Logs:
std::transform(paths.begin(), paths.end(), std::back_inserter(result), [](auto &path){
return (path / "logs").string();
});
break;
default: __builtin_unreachable();
}
#elif defined(OS_MACOS)
@ -137,6 +142,9 @@ namespace hex {
case ImHexPath::Constants:
result.push_back((applicationSupportDir / "constants").string());
break;
case ImHexPath::Logs:
result.push_back((applicationSupportDir / "logs").string());
break;
default: __builtin_unreachable();
}
#else
@ -191,6 +199,10 @@ namespace hex {
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "constants").string(); });
break;
case ImHexPath::Logs:
std::transform(dataDirs.begin(), dataDirs.end(), std::back_inserter(result),
[](auto p) { return (p / "logs").string(); });
break;
default: __builtin_unreachable();
}
#endif

View File

@ -16,17 +16,18 @@ namespace hex {
class Plugin {
public:
Plugin(const fs::path &path);
explicit Plugin(const fs::path &path);
Plugin(const Plugin&) = delete;
Plugin(Plugin &&other) noexcept;
~Plugin();
void initializePlugin() const;
[[nodiscard]] bool initializePlugin() const;
[[nodiscard]] std::string getPluginName() const;
[[nodiscard]] std::string getPluginAuthor() const;
[[nodiscard]] std::string getPluginDescription() const;
void setImGuiContext(ImGuiContext *ctx) const;
[[nodiscard]] const fs::path& getPath() const;
private:
using InitializePluginFunc = void(*)();
@ -36,6 +37,7 @@ namespace hex {
using SetImGuiContextFunc = void(*)(ImGuiContext*);
void *m_handle = nullptr;
fs::path m_path;
InitializePluginFunc m_initializePluginFunction = nullptr;
GetPluginNameFunc m_getPluginNameFunction = nullptr;

View File

@ -14,7 +14,7 @@ namespace hex {
constexpr auto GetPluginDescriptionSymbol = "_ZN3hex6plugin{0}{1}8internal20getPluginDescriptionEv";
constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin{0}{1}8internal15setImGuiContextEP12ImGuiContext";
Plugin::Plugin(const fs::path &path) {
Plugin::Plugin(const fs::path &path) : m_path(path) {
this->m_handle = dlopen(path.string().c_str(), RTLD_LAZY);
if (this->m_handle == nullptr) {
@ -33,6 +33,8 @@ namespace hex {
Plugin::Plugin(Plugin &&other) noexcept {
this->m_handle = other.m_handle;
this->m_path = std::move(other.m_path);
this->m_initializePluginFunction = other.m_initializePluginFunction;
this->m_getPluginNameFunction = other.m_getPluginNameFunction;
this->m_getPluginAuthorFunction = other.m_getPluginAuthorFunction;
@ -52,9 +54,13 @@ namespace hex {
dlclose(this->m_handle);
}
void Plugin::initializePlugin() const {
if (this->m_initializePluginFunction != nullptr)
bool Plugin::initializePlugin() const {
if (this->m_initializePluginFunction != nullptr) {
this->m_initializePluginFunction();
return true;
} else {
return false;
}
}
std::string Plugin::getPluginName() const {
@ -83,6 +89,12 @@ namespace hex {
this->m_setImGuiContextFunction(ctx);
}
const fs::path &Plugin::getPath() const {
return this->m_path;
}
bool PluginManager::load(const fs::path &pluginFolder) {
if (!fs::exists(pluginFolder))
return false;

View File

@ -49,7 +49,8 @@ namespace hex::init {
try {
status = task() && status;
} catch (...) {
} catch (std::exception &e) {
log::error("Init task {} threw an exception: {}", name, e.what());
status = false;
}

View File

@ -57,7 +57,7 @@ namespace hex::init {
bool createDirectories() {
bool result = true;
std::array paths = {
constexpr std::array paths = {
ImHexPath::Patterns,
ImHexPath::PatternsInclude,
ImHexPath::Magic,
@ -66,7 +66,8 @@ namespace hex::init {
ImHexPath::Config,
ImHexPath::Constants,
ImHexPath::Yara,
ImHexPath::Python
ImHexPath::Python,
ImHexPath::Logs
};
for (auto path : paths) {
@ -225,7 +226,8 @@ namespace hex::init {
}
for (const auto &plugin : PluginManager::getPlugins()) {
plugin.initializePlugin();
if (!plugin.initializePlugin())
log::error("Failed to initialize plugin {}", plugin.getPath().filename().string());
}
return true;

View File

@ -3,13 +3,18 @@
#if defined(OS_LINUX)
#include <hex/helpers/utils.hpp>
#include <hex/helpers/logger.hpp>
#include <nlohmann/json.hpp>
#include <sys/wait.h>
#include <unistd.h>
namespace hex {
void Window::initNative() {
if (!isatty(STDOUT_FILENO)) {
log::redirectToFile();
}
}
void Window::setupNativeWindow() {

View File

@ -2,12 +2,17 @@
#if defined(OS_MACOS)
#include <hex/helpers/logger.hpp>
#include <nlohmann/json.hpp>
#include <unistd.h>
namespace hex {
void Window::initNative() {
if (!isatty(STDOUT_FILENO)) {
log::redirectToFile();
}
}
void Window::setupNativeWindow() {

View File

@ -172,25 +172,26 @@
// Redirect cin, cout and cerr to that console
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONERR$", "w", stderr);
freopen("CONOUT$", "w", stderr);
setvbuf(stdin, nullptr, _IONBF, 0);
setvbuf(stdout, nullptr, _IONBF, 0);
setvbuf(stderr, nullptr, _IONBF, 0);
fmt::print("\n");
}
// Enable color format specifiers in console
{
auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE) {
DWORD mode = 0;
if (::GetConsoleMode(hConsole, &mode)) {
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
::SetConsoleMode(hConsole, mode);
// Enable color format specifiers in console
{
auto hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (hConsole != INVALID_HANDLE_VALUE) {
DWORD mode = 0;
if (::GetConsoleMode(hConsole, &mode)) {
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT;
::SetConsoleMode(hConsole, mode);
}
}
}
} else {
log::redirectToFile();
}
// Open new files in already existing ImHex instance