Merge pull request #329 from DrDoof/feat/cmd-output

httpd: answer /cmd with what the command printed, and show it in the console tab
This commit is contained in:
René van Dorst authored and GitHub committed 2026-09-03 20:33:26 +00:00
commit 6c43091b7a
7 files changed
+63 -6

No files matched your search

+2
View File
@@ -88,6 +88,8 @@
<input style="width:20%;" class="action" id="cmd_sub" onclick="cmdSub();" type="button" data-i18n="sys_send_cmd" value="Send Command"><br/>
<br/><br/>
<span data-i18n="sys_console_warn">Be careful when entering console commands, you can lock yourself out!</span><br/>
<br/>
<pre id="console_out" style="height:22em;overflow:auto;white-space:pre-wrap;border:1px solid;padding:0.5em;"></pre>
</div>
+16 -2
View File
@@ -35,14 +35,28 @@ async function ipSub() {
}
async function cmdSub() {
var cmd = document.getElementById('console_cmd').value;
const input = document.getElementById('console_cmd');
const out = document.getElementById('console_out');
const cmd = input.value;
try {
const response = await fetch('/cmd', {
method: 'POST',
body: cmd
});
console.log('Completed!', response);
if (response.status == 401) {
window.location.href = 'login.html';
return;
}
let text = await response.text();
if (text != "" && !text.endsWith("\n"))
text += "\n";
if (out.textContent.length > 20000)
out.textContent = out.textContent.slice(-16000);
out.textContent += "> " + cmd + "\n" + text;
out.scrollTop = out.scrollHeight;
input.value = "";
} catch(err) {
out.textContent += "> " + cmd + "\n" + err + "\n";
console.error(`Error: ${err}`);
}
}
+21 -3
View File
@@ -21,6 +21,7 @@
extern volatile __xdata uint8_t sfr_data[4];
extern volatile __xdata uint32_t ticks;
extern __xdata uint8_t cmd_capture; /* owned by rtlplayground.c, see write_char_no_syslog() */
extern __code uint8_t * __code hex;
extern __code struct f_data f_data[];
extern __code char * __code mime_strings[];
@@ -625,12 +626,29 @@ static void handle_firmware_fragment(__xdata uint8_t *p)
static void run_cmd_body(__xdata uint8_t *body)
{
uint16_t hdr_len = strtox(outbuf, HTTP_RESPONCE_TXT);
slen = hdr_len;
cmd_capture = 1;
execute_commands(body);
if (cmd_capture == 2)
slen += strtox(outbuf + slen, CMD_TRUNCATED);
cmd_capture = 0;
/* Commands that configure something print nothing at all. Saying
* so beats an empty body, which reads the same as "nothing ran".
* Only on success: a silent failure must not answer with "OK". */
if (err_status == ERR_OK && slen == hdr_len)
slen += strtox(outbuf + slen, "OK\n");
/* On a parse error keep what the parser printed, because that text
* is the explanation, and only restate the status. "400 NO" is as
* long as "200 OK", so the header does not have to be rebuilt. */
if (err_status != ERR_OK) {
send_bad_request();
return;
outbuf[9] = '4';
outbuf[10] = '0';
outbuf[11] = '0';
outbuf[13] = 'N';
outbuf[14] = 'O';
}
send_ok();
}
+1 -1
View File
@@ -48,7 +48,7 @@ extern __xdata char sfp_module_serial[2][17];
extern __xdata uint8_t sfp_options[2];
__code uint8_t * __code HTTP_RESPONCE_JSON = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: application/json\r\n\r\n";
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
__code uint8_t * __code HTTP_RESPONCE_TXT = "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: text/plain\r\n\r\n";
// Convert uint8_t to ascii HEX char push on html-buffer.
void charhex_to_html(char c)
+2
View File
@@ -3,6 +3,8 @@
#include <stdbool.h>
extern __code uint8_t * __code HTTP_RESPONCE_TXT;
bool send_counters(uint8_t phys_port);
void send_status(void);
void send_vlan(uint16_t vlan);
+4
View File
@@ -37,6 +37,10 @@ extern __xdata uint8_t sbuf[SBUF_SIZE];
// Size of the TCP Output buffer
#define TCP_OUTBUF_SIZE 2500
// Appended when a captured command wrote more than the output buffer holds,
// so a clipped listing is visibly clipped instead of silently short.
#define CMD_TRUNCATED "\n[output truncated]\n"
// Size of the port name, including the terminating null byte
#define PORT_NAME_SIZE 32
+17
View File
@@ -240,8 +240,25 @@ void isr_serial(void) __interrupt(4)
}
/* Set by the httpd while it runs a command that arrived over the network, so
* that everything the command prints lands in the response as well. */
__xdata uint8_t cmd_capture;
extern __xdata uint8_t outbuf[TCP_OUTBUF_SIZE];
extern __xdata uint16_t slen;
void write_char_no_syslog(char c)
{
/* Capturing sits here rather than in write_char() so that the messages
* printed through print_string_no_syslog() are captured too: those are
* the replies of the syslog commands, which must not generate a syslog
* packet but do belong in the answer to a command sent over HTTP. */
if (cmd_capture) {
if (slen < TCP_OUTBUF_SIZE - sizeof(CMD_TRUNCATED))
outbuf[slen++] = c;
else
cmd_capture = 2; /* out of room, httpd says so */
}
do {
} while (tx_buf_empty == 0);
if (c =='\n') {