Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
cmake --build . --config Release

- name: Test binary exists
shell: bash
run: |
if [ "${{ matrix.os }}" == "windows-latest" ]; then
test -f build/Release/smartproxy.exe || test -f build/smartproxy.exe
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
cc: arm-linux-gnueabihf-gcc
cxx: arm-linux-gnueabihf-g++
cross: true
cflags: -march=armv6 -mfpu=vfp -mfloat-abi=hard
cflags: -march=armv6 -mfpu=vfp -mfloat-abi=softfp -marm
# Linux MIPS64
- os: ubuntu-latest
target: linux
Expand Down
12 changes: 9 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,19 @@ else()
# Allow cross-compilation flags from environment
if(CMAKE_CROSSCOMPILING)
if(DEFINED ENV{CFLAGS})
target_compile_options(smartproxy PRIVATE $ENV{CFLAGS})
# Convert space-separated string to CMake list
string(REPLACE " " ";" CFLAGS_LIST "$ENV{CFLAGS}")
target_compile_options(smartproxy PRIVATE ${CFLAGS_LIST})
endif()
if(DEFINED ENV{CXXFLAGS})
target_compile_options(smartproxy PRIVATE $ENV{CXXFLAGS})
# Convert space-separated string to CMake list
string(REPLACE " " ";" CXXFLAGS_LIST "$ENV{CXXFLAGS}")
target_compile_options(smartproxy PRIVATE ${CXXFLAGS_LIST})
endif()
if(DEFINED ENV{LDFLAGS})
target_link_options(smartproxy PRIVATE $ENV{LDFLAGS})
# Convert space-separated string to CMake list
string(REPLACE " " ";" LDFLAGS_LIST "$ENV{LDFLAGS}")
target_link_options(smartproxy PRIVATE ${LDFLAGS_LIST})
endif()
endif()
endif()
Expand Down
11 changes: 11 additions & 0 deletions health.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#include "health.h"
#include <chrono>
#include <thread>
#include <algorithm>

// Undefine Windows min/max macros that conflict with std::min/std::max
#ifdef _WIN32
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#endif

HealthMonitor::HealthMonitor(
std::shared_ptr<RunwayManager> runway_manager,
Expand Down
14 changes: 11 additions & 3 deletions logger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,22 @@ void Logger::close() {

std::string Logger::format_timestamp(uint64_t timestamp) {
std::time_t time_val = static_cast<std::time_t>(timestamp);
std::tm* tm_info = std::localtime(&time_val);
std::tm tm_info;

if (!tm_info) {
#ifdef _WIN32
// Use localtime_s on Windows (thread-safe)
if (localtime_s(&tm_info, &time_val) != 0) {
return "0000-00-00 00:00:00";
}
#else
// Use localtime_r on POSIX (thread-safe)
if (localtime_r(&time_val, &tm_info) == nullptr) {
return "0000-00-00 00:00:00";
}
#endif

std::stringstream ss;
ss << std::put_time(tm_info, "%Y-%m-%d %H:%M:%S");
ss << std::put_time(&tm_info, "%Y-%m-%d %H:%M:%S");
return ss.str();
}

Expand Down
97 changes: 42 additions & 55 deletions tui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,27 @@
#include <windows.h>
#include <io.h>
#include <conio.h>
// Undefine Windows min/max macros that conflict with std::min/std::max
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#else
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <fcntl.h>
#endif

// Cross-platform unused parameter macro
#ifdef _WIN32
#define UNUSED_PARAM(x)
#else
#define UNUSED_PARAM(x) __attribute__((unused))
#endif

TUI::TUI(std::shared_ptr<RunwayManager> runway_manager,
std::shared_ptr<RoutingEngine> routing_engine,
std::shared_ptr<TargetAccessibilityTracker> tracker,
Expand Down Expand Up @@ -344,65 +358,31 @@ void TUI::draw() {
return;
}

// Calculate available space with margins
int available_rows = rows - MARGIN_TOP - MARGIN_BOTTOM;
int available_cols = cols - MARGIN_LEFT - MARGIN_RIGHT;

if (available_rows < 10 || available_cols < 60) {
std::cout << "\033[2J\033[1;1H";
std::cout << "Terminal too small after margins\n";
std::cout.flush();
return;
}

// Build entire frame in stringstream for single atomic output
std::stringstream output;
output << "\033[2J\033[1;1H"; // Clear screen and move to top

// Add top margin (blank lines)
for (int i = 0; i < MARGIN_TOP; ++i) {
output << "\n";
}

// Helper lambda to add left margin
auto add_left_margin = [&]() {
for (int i = 0; i < MARGIN_LEFT; ++i) {
output << " ";
}
};

// Draw detail view if active
if (detail_view_) {
add_left_margin();
draw_detail_view(output, available_cols, available_rows);
draw_detail_view(output, cols, rows);
} else {
// Status bar
add_left_margin();
draw_status_bar(output, available_cols);
draw_status_bar(output, cols);

// Tab bar
add_left_margin();
draw_tab_bar(output, available_cols);
draw_tab_bar(output, cols);

// Content area (remaining space) - use centralized constants
int content_h = available_rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;
int content_h = rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;

// Content
add_left_margin();
draw_content_area(output, available_cols, content_h);
draw_content_area(output, cols, content_h);

// Summary bar
add_left_margin();
draw_summary_bar(output, available_cols);
draw_summary_bar(output, cols);

// Command bar
add_left_margin();
draw_command_bar(output, available_cols);
}

// Add bottom margin (blank lines)
for (int i = 0; i < MARGIN_BOTTOM; ++i) {
output << "\n";
draw_command_bar(output, cols);
}

// Single atomic output for maximum responsiveness
Expand Down Expand Up @@ -620,9 +600,9 @@ void TUI::draw_status_bar(std::stringstream& output, int cols) {
" | Total: " + std::to_string(proxy_server_->get_total_connections());

// Calculate actual visible width (ANSI codes don't count)
int title_len = title.length();
int status_len = status_text.length();
int metrics_len = metrics.length();
int title_len = static_cast<int>(title.length());
int status_len = static_cast<int>(status_text.length());
int metrics_len = static_cast<int>(metrics.length());
int space_len = 1; // Space between status and metrics

int total_content_len = title_len + status_len + metrics_len + space_len;
Expand Down Expand Up @@ -716,7 +696,7 @@ void TUI::draw_content_area(std::stringstream& output, int cols, int max_rows) {
// Table rendering helpers
void TUI::draw_table_border(std::stringstream& output, const std::string& title, int cols) {
output << "┌─ " << title;
int used = 3 + title.length();
int used = 3 + static_cast<int>(title.length());
for (int i = used; i < cols - 1; ++i) {
output << "─";
}
Expand All @@ -729,7 +709,7 @@ void TUI::draw_table_header(std::stringstream& output, const std::vector<std::pa
std::string header = col.first;
int width = col.second;
output << " " << header;
int padding = width - header.length() - 1;
int padding = width - static_cast<int>(header.length()) - 1;
for (int i = 0; i < padding; ++i) {
output << " ";
}
Expand Down Expand Up @@ -787,7 +767,7 @@ void TUI::draw_table_row(std::stringstream& output, const std::vector<std::strin
}

output << " " << cell;
int padding = width - cell.length() - 1;
int padding = width - static_cast<int>(cell.length()) - 1;
for (int j = 0; j < padding; ++j) {
output << " ";
}
Expand Down Expand Up @@ -1167,7 +1147,10 @@ void TUI::draw_stats_tab(std::stringstream& output, int cols, int /*max_rows*/)
output << "┘\n";
}

void TUI::draw_help_tab(std::stringstream& output, int cols, int max_rows __attribute__((unused))) {
void TUI::draw_help_tab(std::stringstream& output, int cols, int max_rows UNUSED_PARAM(max_rows)) {
#ifdef _WIN32
(void)max_rows; // Suppress unused parameter warning on Windows
#endif
std::string title = "Help & Shortcuts";
draw_table_border(output, title, cols);

Expand Down Expand Up @@ -1204,7 +1187,7 @@ void TUI::draw_help_tab(std::stringstream& output, int cols, int max_rows __attr
for (const auto& shortcut : shortcuts) {
output << "│ " << std::setw(12) << std::left << shortcut.first;
output << " " << shortcut.second;
int used = 15 + shortcut.first.length() + shortcut.second.length();
int used = 15 + static_cast<int>(shortcut.first.length() + shortcut.second.length());
for (int i = used; i < cols - 1; ++i) output << " ";
output << "│\n";
}
Expand All @@ -1230,7 +1213,7 @@ void TUI::draw_help_tab(std::stringstream& output, int cols, int max_rows __attr
for (const auto& op : mouse_ops) {
output << "│ " << std::setw(15) << std::left << op.first;
output << " " << op.second;
int used = 18 + op.first.length() + op.second.length();
int used = 18 + static_cast<int>(op.first.length() + op.second.length());
for (int i = used; i < cols - 1; ++i) output << " ";
output << "│\n";
}
Expand Down Expand Up @@ -1264,8 +1247,8 @@ void TUI::draw_summary_bar(std::stringstream& output, int cols) {
std::string separator = " | ";

// Calculate visible length (3 separators between 4 items)
int visible_len = stats_label.length() + runways_text.length() + targets_text.length() +
conns_text.length() + throughput_text.length() + (3 * separator.length());
int visible_len = static_cast<int>(stats_label.length() + runways_text.length() + targets_text.length() +
conns_text.length() + throughput_text.length() + (3 * separator.length()));

// Output with ANSI codes for bold "Stats:"
output << "\033[1m" << stats_label << "\033[0m";
Expand Down Expand Up @@ -1293,7 +1276,7 @@ void TUI::draw_command_bar(std::stringstream& output, int cols) {
}

output << command_text;
int used = command_text.length();
int used = static_cast<int>(command_text.length());

// Fill remaining space with background color
fill_line_with_bg(output, used, cols, bg_color);
Expand All @@ -1307,7 +1290,7 @@ void TUI::draw_detail_view(std::stringstream& output, int cols, int rows) {
output << bg_color;
std::string title = " Detail View ";
output << title;
int used = title.length();
int used = static_cast<int>(title.length());

// Fill remaining space with background color
fill_line_with_bg(output, used, cols, bg_color);
Expand Down Expand Up @@ -1646,7 +1629,11 @@ void TUI::handle_mouse_click(int button, int x, int y) {
}
}

void TUI::handle_mouse_scroll(int direction, int x __attribute__((unused)), int y __attribute__((unused))) {
void TUI::handle_mouse_scroll(int direction, int x UNUSED_PARAM(x), int y UNUSED_PARAM(y)) {
#ifdef _WIN32
(void)x; // Suppress unused parameter warning on Windows
(void)y;
#endif
if (detail_view_ || current_tab_ == Tab::Stats || current_tab_ == Tab::Help) {
return;
}
Expand Down
5 changes: 0 additions & 5 deletions tui.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,6 @@ class TUI {
bool quit_confirmed_; // Quit confirmation flag

// Layout constants - centralized for safe TUI rendering
// Change these to adjust margins dynamically
static constexpr int MARGIN_TOP = 1;
static constexpr int MARGIN_BOTTOM = 1;
static constexpr int MARGIN_LEFT = 2;
static constexpr int MARGIN_RIGHT = 2;
static constexpr int STATUS_BAR_HEIGHT = 1;
static constexpr int TAB_BAR_HEIGHT = 1;
static constexpr int SUMMARY_BAR_HEIGHT = 1;
Expand Down
34 changes: 17 additions & 17 deletions tui_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@
#include <iostream>
#include <cstring>
#include <ctime>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>

#ifdef _WIN32
#include <windows.h>
#include <conio.h>
// Undefine Windows min/max macros that conflict with std::min/std::max
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#else
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/time.h>
#include <termios.h>
#include <fcntl.h>
#endif

// Non-blocking keyboard input handling (zero dependencies, standard library only)
Expand Down Expand Up @@ -377,9 +381,8 @@ void TUI::navigate_page_up() {
// Calculate visible items based on terminal size
int rows = get_terminal_rows();

// Account for margins and UI elements - use centralized constants
int available_rows = rows - MARGIN_TOP - MARGIN_BOTTOM;
int content_h = available_rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;
// Account for UI elements - use centralized constants
int content_h = rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;

// Visible items in the content area (minus header and borders)
int visible_items = content_h - 3; // Leave space for header and borders
Expand All @@ -405,9 +408,8 @@ void TUI::navigate_page_down() {
// Calculate visible items based on terminal size
int rows = get_terminal_rows();

// Account for margins and UI elements - use centralized constants
int available_rows = rows - MARGIN_TOP - MARGIN_BOTTOM;
int content_h = available_rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;
// Account for UI elements - use centralized constants
int content_h = rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;

// Visible items in the content area (minus header and borders)
int visible_items = content_h - 3; // Leave space for header and borders
Expand All @@ -431,9 +433,8 @@ void TUI::navigate_half_page_up() {
// Calculate visible items based on terminal size
int rows = get_terminal_rows();

// Account for margins and UI elements - use centralized constants
int available_rows = rows - MARGIN_TOP - MARGIN_BOTTOM;
int content_h = available_rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;
// Account for UI elements - use centralized constants
int content_h = rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;

// Half page = half of visible items
int visible_items = content_h - 3;
Expand Down Expand Up @@ -461,9 +462,8 @@ void TUI::navigate_half_page_down() {
// Calculate visible items based on terminal size
int rows = get_terminal_rows();

// Account for margins and UI elements - use centralized constants
int available_rows = rows - MARGIN_TOP - MARGIN_BOTTOM;
int content_h = available_rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;
// Account for UI elements - use centralized constants
int content_h = rows - STATUS_BAR_HEIGHT - TAB_BAR_HEIGHT - SUMMARY_BAR_HEIGHT - COMMAND_BAR_HEIGHT;

// Half page = half of visible items
int visible_items = content_h - 3;
Expand Down
Loading