Add uname, /uname and scp (key or masked password) in the Shell
CI / build (pull_request) Failing after 1m59s
Site / build (pull_request) Successful in 9s

- uname in the console and /uname in IRC: the firmware, its version and the chip
- scp: one file between the card and a trusted server, over SSH, with the
  device's key or a password asked (masked) in the Shell
- shared libssh helpers in src/platform/libssh_util
- README, user guide, command reference and a how-to updated

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
This commit is contained in:
2026-10-09 19:01:36 +02:00
co-authored by Claude Sonnet 5.5
parent e707a5f2d4
commit 18285c3212
25 changed files with 730 additions and 34 deletions
@@ -330,6 +330,18 @@ void test_action_and_ctcp_version() {
TEST_ASSERT_TRUE(f.sent(std::string("NOTICE alice :\x01VERSION roro9stack ") + versionString() + "\x01"));
}
void test_uname_shows_the_firmware_here_and_sends_nothing() {
Fixture f;
f.registerNow();
f.recv(":roro!u@h JOIN #roro");
f.take();
f.session->input(f.buffer("#roro"), "/uname", 0);
const auto& line = f.session->buffer(f.buffer("#roro")).lines.back();
TEST_ASSERT_EQUAL(static_cast<int>(IrcLine::Kind::Info), static_cast<int>(line.kind));
TEST_ASSERT_EQUAL_STRING(unameString().c_str(), line.text.c_str());
TEST_ASSERT_EQUAL(0, f.take().send.size());
}
void test_topic_is_kept() {
Fixture f;
f.registerNow();
@@ -492,6 +504,7 @@ int main() {
RUN_TEST(test_private_message_opens_a_query_buffer_and_notifies);
RUN_TEST(test_no_notification_while_viewing_that_buffer);
RUN_TEST(test_action_and_ctcp_version);
RUN_TEST(test_uname_shows_the_firmware_here_and_sends_nothing);
RUN_TEST(test_topic_is_kept);
RUN_TEST(test_input_message_and_commands);
RUN_TEST(test_j_is_short_for_join);