diff --git a/kernel/src/Api/BuildNo.hpp b/kernel/src/Api/BuildNo.hpp index 7651bc4..ceebd47 100644 --- a/kernel/src/Api/BuildNo.hpp +++ b/kernel/src/Api/BuildNo.hpp @@ -12,4 +12,4 @@ #pragma once -#define MONTAUK_BUILD_NUMBER 150 +#define MONTAUK_BUILD_NUMBER 151 diff --git a/programs/include/montauk/service_log.h b/programs/include/montauk/service_log.h new file mode 100644 index 0000000..b54fe6b --- /dev/null +++ b/programs/include/montauk/service_log.h @@ -0,0 +1,24 @@ +/* + * service_log.h + * Common logging policy for MontaukOS userspace services. + */ + +#pragma once + +#include + +namespace montauk { + +// Append one newline-free message to the system log. When the service was +// launched from a userspace terminal, echo the same message there as well. +inline void service_log(const char* message) { + if (message == nullptr) return; + + write_log(message); + if (terminal_attached()) { + print(message); + print("\n"); + } +} + +} diff --git a/programs/src/dhcp/main.cpp b/programs/src/dhcp/main.cpp index 798feac..9a7a658 100644 --- a/programs/src/dhcp/main.cpp +++ b/programs/src/dhcp/main.cpp @@ -6,6 +6,7 @@ */ #include +#include #include #include @@ -247,7 +248,7 @@ static constexpr uint32_t BROADCAST_IP = 0xFFFFFFFF; extern "C" void _start() { char msg[256]; - montauk::print("MontaukOS DHCP Client\n"); + montauk::service_log("MontaukOS DHCP Client"); // 1. Get MAC address montauk::abi::NetCfg origCfg; @@ -255,8 +256,8 @@ extern "C" void _start() { char macStr[32]; format_mac(macStr, sizeof(macStr), origCfg.macAddress); - snprintf(msg, sizeof(msg), "MAC address: %s\n", macStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), "MAC address: %s", macStr); + montauk::service_log(msg); // 2. Set IP to 0.0.0.0 to allow broadcast send/receive montauk::abi::NetCfg zeroCfg; @@ -268,13 +269,13 @@ extern "C" void _start() { // 3. Create UDP socket and bind to port 68 int fd = montauk::socket(montauk::abi::SOCK_UDP); if (fd < 0) { - montauk::print("Error: failed to create UDP socket\n"); + montauk::service_log("Error: failed to create UDP socket"); montauk::set_netcfg(&origCfg); montauk::exit(1); } if (montauk::bind(fd, DHCP_CLIENT_PORT) < 0) { - montauk::print("Error: failed to bind to port 68\n"); + montauk::service_log("Error: failed to bind to port 68"); montauk::closesocket(fd); montauk::set_netcfg(&origCfg); montauk::exit(1); @@ -284,9 +285,9 @@ extern "C" void _start() { DhcpPacket pkt; int pktLen = build_discover(&pkt, origCfg.macAddress); - montauk::print("Sending DHCPDISCOVER...\n"); + montauk::service_log("Sending DHCPDISCOVER..."); if (montauk::sendto(fd, (const void*)&pkt, pktLen, BROADCAST_IP, DHCP_SERVER_PORT) < 0) { - montauk::print("Error: failed to send DISCOVER\n"); + montauk::service_log("Error: failed to send DISCOVER"); montauk::closesocket(fd); montauk::set_netcfg(&origCfg); montauk::exit(1); @@ -298,7 +299,7 @@ extern "C" void _start() { uint64_t startMs = montauk::get_milliseconds(); bool gotOffer = false; - montauk::print("Waiting for DHCPOFFER...\n"); + montauk::service_log("Waiting for DHCPOFFER..."); while (montauk::get_milliseconds() - startMs < 10000) { uint32_t srcIp; uint16_t srcPort; @@ -318,7 +319,7 @@ extern "C" void _start() { } if (!gotOffer) { - montauk::print("Error: no DHCPOFFER received (timeout)\n"); + montauk::service_log("Error: no DHCPOFFER received (timeout)"); montauk::closesocket(fd); montauk::set_netcfg(&origCfg); montauk::exit(1); @@ -326,15 +327,15 @@ extern "C" void _start() { char ipStr[32]; format_ip(ipStr, sizeof(ipStr), offer.offeredIp); - snprintf(msg, sizeof(msg), "Received OFFER: %s\n", ipStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), "Received OFFER: %s", ipStr); + montauk::service_log(msg); // 6. Send REQUEST pktLen = build_request(&pkt, origCfg.macAddress, offer.offeredIp, offer.serverId); - montauk::print("Sending DHCPREQUEST...\n"); + montauk::service_log("Sending DHCPREQUEST..."); if (montauk::sendto(fd, (const void*)&pkt, pktLen, BROADCAST_IP, DHCP_SERVER_PORT) < 0) { - montauk::print("Error: failed to send REQUEST\n"); + montauk::service_log("Error: failed to send REQUEST"); montauk::closesocket(fd); montauk::set_netcfg(&origCfg); montauk::exit(1); @@ -344,7 +345,7 @@ extern "C" void _start() { bool gotAck = false; startMs = montauk::get_milliseconds(); - montauk::print("Waiting for DHCPACK...\n"); + montauk::service_log("Waiting for DHCPACK..."); while (montauk::get_milliseconds() - startMs < 10000) { uint32_t srcIp; uint16_t srcPort; @@ -357,7 +358,7 @@ extern "C" void _start() { break; } if (offer.valid && offer.msgType == DHCPNAK) { - montauk::print("Error: received DHCPNAK from server\n"); + montauk::service_log("Error: received DHCPNAK from server"); montauk::closesocket(fd); montauk::set_netcfg(&origCfg); montauk::exit(1); @@ -372,7 +373,7 @@ extern "C" void _start() { montauk::closesocket(fd); if (!gotAck) { - montauk::print("Error: no DHCPACK received (timeout)\n"); + montauk::service_log("Error: no DHCPACK received (timeout)"); montauk::set_netcfg(&origCfg); montauk::exit(1); } @@ -386,29 +387,29 @@ extern "C" void _start() { montauk::set_netcfg(&newCfg); // 9. Print results - montauk::print("\nDHCP configuration applied:\n"); + montauk::service_log("DHCP configuration applied:"); format_ip(ipStr, sizeof(ipStr), offer.offeredIp); - snprintf(msg, sizeof(msg), " IP Address: %s\n", ipStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), " IP Address: %s", ipStr); + montauk::service_log(msg); format_ip(ipStr, sizeof(ipStr), offer.subnetMask); - snprintf(msg, sizeof(msg), " Subnet Mask: %s\n", ipStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), " Subnet Mask: %s", ipStr); + montauk::service_log(msg); format_ip(ipStr, sizeof(ipStr), offer.router); - snprintf(msg, sizeof(msg), " Gateway: %s\n", ipStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), " Gateway: %s", ipStr); + montauk::service_log(msg); if (offer.dns != 0) { format_ip(ipStr, sizeof(ipStr), offer.dns); - snprintf(msg, sizeof(msg), " DNS Server: %s\n", ipStr); - montauk::print(msg); + snprintf(msg, sizeof(msg), " DNS Server: %s", ipStr); + montauk::service_log(msg); } if (offer.leaseTime != 0) { - snprintf(msg, sizeof(msg), " Lease Time: %u seconds\n", offer.leaseTime); - montauk::print(msg); + snprintf(msg, sizeof(msg), " Lease Time: %u seconds", offer.leaseTime); + montauk::service_log(msg); } montauk::exit(0); diff --git a/programs/src/httpd/main.cpp b/programs/src/httpd/main.cpp index 2a048e6..25a4191 100644 --- a/programs/src/httpd/main.cpp +++ b/programs/src/httpd/main.cpp @@ -7,6 +7,7 @@ */ #include +#include #include #include @@ -144,10 +145,10 @@ static void log_request(const char* method, const char* path, int status, int bo montauk::gettime(&dt); char msg[256]; - snprintf(msg, sizeof(msg), "[%02d:%02d:%02d] %s %s -> %d (%d bytes)\n", + snprintf(msg, sizeof(msg), "[%02d:%02d:%02d] %s %s -> %d (%d bytes)", (int)dt.Hour, (int)dt.Minute, (int)dt.Second, method, path, status, bodyLen); - montauk::print(msg); + montauk::service_log(msg); } // ---- Page generators ---- @@ -454,9 +455,9 @@ extern "C" void _start() { uint16_t port = 80; if (*arg) { if (!parse_uint16(arg, &port)) { - montauk::print("Invalid port: "); - montauk::print(arg); - montauk::putchar('\n'); + char message[96]; + snprintf(message, sizeof(message), "Invalid port: %s", arg); + montauk::service_log(message); montauk::exit(1); } } @@ -464,32 +465,30 @@ extern "C" void _start() { // Create server socket int listenFd = montauk::socket(montauk::abi::SOCK_TCP); if (listenFd < 0) { - montauk::print("Error: failed to create socket\n"); + montauk::service_log("Error: failed to create socket"); montauk::exit(1); } // Bind if (montauk::bind(listenFd, port) < 0) { - montauk::print("Error: failed to bind to port "); - char tmp[8]; - snprintf(tmp, sizeof(tmp), "%d", (int)port); - montauk::print(tmp); - montauk::putchar('\n'); + char message[64]; + snprintf(message, sizeof(message), "Error: failed to bind to port %d", (int)port); + montauk::service_log(message); montauk::closesocket(listenFd); montauk::exit(1); } // Listen if (montauk::listen(listenFd) < 0) { - montauk::print("Error: failed to listen\n"); + montauk::service_log("Error: failed to listen"); montauk::closesocket(listenFd); montauk::exit(1); } char msg[128]; - snprintf(msg, sizeof(msg), "MontaukOS httpd listening on port %d\n", (int)port); - montauk::print(msg); - montauk::print("Press Ctrl+Q between requests to stop.\n\n"); + snprintf(msg, sizeof(msg), "MontaukOS httpd listening on port %d", (int)port); + montauk::service_log(msg); + montauk::service_log("Press Ctrl+Q between requests to stop."); bool running = true; while (running) { @@ -507,7 +506,7 @@ extern "C" void _start() { // Accept next client (blocks until a connection arrives) int clientFd = montauk::accept(listenFd); if (clientFd < 0) { - montauk::print("Warning: accept failed\n"); + montauk::service_log("Warning: accept failed"); montauk::yield(); continue; } @@ -525,7 +524,7 @@ extern "C" void _start() { } } - montauk::print("\nShutting down httpd...\n"); + montauk::service_log("Shutting down httpd..."); montauk::closesocket(listenFd); montauk::exit(0); } diff --git a/programs/src/ntp/main.cpp b/programs/src/ntp/main.cpp index b570efa..c1a8505 100644 --- a/programs/src/ntp/main.cpp +++ b/programs/src/ntp/main.cpp @@ -6,8 +6,10 @@ #include #include +#include #include #include +#include static constexpr uint64_t RETRY_INTERVAL_MS = montauk::ntp::MIN_QUERY_INTERVAL_MS; @@ -15,9 +17,9 @@ static constexpr uint64_t SYNC_INTERVAL_MS = 60ULL * 60ULL * 1000ULL; static constexpr uint64_t CONFIG_POLL_MS = 5000; static void log(const char* message) { - montauk::print("ntp: "); - montauk::print(message); - montauk::print("\n"); + char line[256]; + snprintf(line, sizeof(line), "ntp: %s", message); + montauk::service_log(line); } static bool load_settings(char* server, int server_cap) { diff --git a/programs/src/printd/main.cpp b/programs/src/printd/main.cpp index 9573626..591316f 100644 --- a/programs/src/printd/main.cpp +++ b/programs/src/printd/main.cpp @@ -5,6 +5,7 @@ */ #include +#include #include #include "test_page_jpeg.hpp" @@ -64,12 +65,15 @@ static void write_daemon_state(const char* phase, const char* subject = nullptr, } static void log_msg(const char* fmt, ...) { + char body[768]; va_list ap; va_start(ap, fmt); - printf("[printd] "); - vprintf(fmt, ap); - printf("\n"); + vsnprintf(body, sizeof(body), fmt, ap); va_end(ap); + + char line[800]; + snprintf(line, sizeof(line), "[printd] %s", body); + montauk::service_log(line); } static void set_job_state(JobMeta* job, const char* state, const char* message) { diff --git a/programs/src/sshd/main.cpp b/programs/src/sshd/main.cpp index b7948c0..6144e89 100644 --- a/programs/src/sshd/main.cpp +++ b/programs/src/sshd/main.cpp @@ -5,6 +5,7 @@ #include "crypto.hpp" +#include #include #include @@ -1287,17 +1288,17 @@ static void handle(int fd) { connection.set_timeout(PREAUTH_TIMEOUT_MS); if (!version(connection)) { - montauk::print("sshd: client version exchange failed\n"); + montauk::service_log("sshd: client version exchange failed"); } else if (!kex(connection)) { char message[64]; snprintf(message, sizeof(message), - "sshd: key exchange failed (%d)\n", kex_error); - montauk::print(message); + "sshd: key exchange failed (%d)", kex_error); + montauk::service_log(message); } else if (!auth(connection, user)) { char message[64]; snprintf(message, sizeof(message), - "sshd: authentication failed (%d)\n", kex_error); - montauk::print(message); + "sshd: authentication failed (%d)", kex_error); + montauk::service_log(message); } else { /* An authenticated session is allowed to sit idle. */ connection.clear_timeout(); @@ -1309,14 +1310,14 @@ static void handle(int fd) { extern "C" void _start() { if (!rng.init()) { - montauk::print("sshd: secure random initialization failed\n"); + montauk::service_log("sshd: secure random initialization failed"); montauk::exit(1); } if (!hostkey.load()) { - montauk::print("sshd: generating local RSA host key...\n"); + montauk::service_log("sshd: generating local RSA host key..."); if (!hostkey.generate(rng)) { - montauk::print("sshd: host key generation failed\n"); + montauk::service_log("sshd: host key generation failed"); montauk::exit(1); } } @@ -1329,13 +1330,13 @@ extern "C" void _start() { int listener = montauk::socket(montauk::abi::SOCK_TCP); if (listener < 0 || montauk::bind(listener, (uint16_t)port) < 0 || montauk::listen(listener) < 0) { - montauk::print("sshd: could not listen\n"); + montauk::service_log("sshd: could not listen"); montauk::exit(1); } char message[80]; - snprintf(message, sizeof(message), "sshd: listening on port %d\n", port); - montauk::print(message); + snprintf(message, sizeof(message), "sshd: listening on port %d", port); + montauk::service_log(message); for (;;) { int fd = montauk::accept(listener); diff --git a/template/sysroot/include/montauk/service_log.h b/template/sysroot/include/montauk/service_log.h new file mode 100644 index 0000000..b54fe6b --- /dev/null +++ b/template/sysroot/include/montauk/service_log.h @@ -0,0 +1,24 @@ +/* + * service_log.h + * Common logging policy for MontaukOS userspace services. + */ + +#pragma once + +#include + +namespace montauk { + +// Append one newline-free message to the system log. When the service was +// launched from a userspace terminal, echo the same message there as well. +inline void service_log(const char* message) { + if (message == nullptr) return; + + write_log(message); + if (terminal_attached()) { + print(message); + print("\n"); + } +} + +}