REMOTE_CONSOLE: reorganized code to use array of structs

The original model started with two array variables each with one element
for each potential concurrent remote console.  As functionality was added
the number of arrays grew to an unreasonable number.  This change
merely gets rid of the separate arrays of per connection info and uses a
single array of REMOTE struct which contains all the per connection info.
This will make future functional extensions much cleaner.
This commit is contained in:
Mark Pizzolato 2017-01-31 21:09:49 -08:00
parent 724b23844c
commit 0913edb2f3

View file

@ -463,16 +463,25 @@ DEVICE sim_remote_console = {
NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL,
NULL, DEV_DEBUG | DEV_NOSAVE, 0, sim_rem_con_debug,
NULL, NULL, NULL, NULL, NULL, sim_rem_con_description};
static int32 *sim_rem_buf_size = NULL;
static int32 *sim_rem_buf_ptr = NULL;
static char **sim_rem_buf = NULL;
static char **sim_rem_act_buf = NULL;
static size_t *sim_rem_act_buf_size = NULL;
static char **sim_rem_act = NULL;
static uint32 *sim_rem_repeat_interval = NULL;
static t_bool *sim_rem_repeat_pending = NULL;
static char **sim_rem_repeat_action = NULL;
static t_bool *sim_rem_single_mode = NULL; /* per line command mode (single command or must continue) */
typedef struct REMOTE REMOTE;
struct REMOTE {
int32 buf_size;
int32 buf_ptr;
char *buf;
char *act_buf;
size_t act_buf_size;
char *act;
uint32 repeat_interval;
t_bool repeat_pending;
char *repeat_action;
t_bool single_mode;
uint32 read_timeout;
int line;
TMLN *lp;
UNIT *uptr;
};
REMOTE *sim_rem_consoles = NULL;
static TMXR sim_rem_con_tmxr = { 0, 0, 0, NULL, NULL, &sim_remote_console };/* remote console line mux */
static uint32 sim_rem_read_timeout = 30; /* seconds before automatic continue */
static uint32 *sim_rem_read_timeouts = NULL;/* per line read timeout (default from sim_rem_read_timeout) */
@ -518,7 +527,7 @@ return SCPE_OK;
t_stat sim_show_remote_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr)
{
int32 i, connections;
TMLN *lp;
REMOTE *rem;
if (*cptr != 0)
return SCPE_NOPARAM;
@ -539,22 +548,22 @@ else {
fprintf (st, "Remote Console Per Command Output buffer size: %d bytes\n", sim_rem_con_tmxr.buffered);
}
for (i=connections=0; i<sim_rem_con_tmxr.lines; i++) {
lp = &sim_rem_con_tmxr.ldsc[i];
if (!lp->conn)
rem = &sim_rem_consoles[i];
if (!rem->lp->conn)
continue;
++connections;
if (connections == 1)
fprintf (st, "Remote Console Connections:\n");
tmxr_fconns (st, lp, i);
if (sim_rem_read_timeouts[i] != sim_rem_read_timeout) {
if (sim_rem_read_timeouts[i])
fprintf (st, "Remote Console Input on connection %d automatically continues after %d seconds\n", i, sim_rem_read_timeouts[i]);
tmxr_fconns (st, rem->lp, i);
if (rem->read_timeout != sim_rem_read_timeout) {
if (rem->read_timeout)
fprintf (st, "Remote Console Input on connection %d automatically continues after %d seconds\n", i, rem->read_timeout);
else
fprintf (st, "Remote Console Input on connection %d does not continue automatically\n", i);
}
if (sim_rem_repeat_action[i]) {
fprintf (st, "The Command: %s\n", sim_rem_repeat_action[i]);
fprintf (st, " is repeated every %s\n", sim_fmt_secs (sim_rem_repeat_interval[i] / 1000000.0));
if (rem->repeat_action) {
fprintf (st, "The Command: %s\n", rem->repeat_action);
fprintf (st, " is repeated every %s\n", sim_fmt_secs (rem->repeat_interval / 1000000.0));
}
}
return SCPE_OK;
@ -568,14 +577,15 @@ int32 c;
c = tmxr_poll_conn (&sim_rem_con_tmxr);
if (c >= 0) { /* poll connect */
TMLN *lp = &sim_rem_con_tmxr.ldsc[c];
REMOTE *rem = &sim_rem_consoles[c];
TMLN *lp = rem->lp;
char wru_name[8];
sim_activate_after(uptr+1, 1000000); /* start data poll after 1 second */
lp->rcve = 1; /* rcv enabled */
sim_rem_buf_ptr[c] = 0; /* start with empty command buffer */
sim_rem_single_mode[c] = TRUE; /* start in single command mode */
sim_rem_read_timeouts[c] = sim_rem_read_timeout; /* Start with default timeout */
rem->buf_ptr = 0; /* start with empty command buffer */
rem->single_mode = TRUE; /* start in single command mode */
rem->read_timeout = sim_rem_read_timeout; /* Start with default timeout */
if (isprint(sim_int_char&0xFF))
sprintf(wru_name, "'%c'", sim_int_char&0xFF);
else
@ -589,7 +599,7 @@ if (c >= 0) { /* poll connect */
sim_name, wru_name,
((sim_rem_master_mode && (c == 0)) ? "" : "\nSimulator Running..."));
if (sim_rem_master_mode && (c == 0)) /* Master Mode session? */
sim_rem_single_mode[c] = FALSE; /* start in multi-command mode */
rem->single_mode = FALSE; /* start in multi-command mode */
tmxr_send_buffered_data (lp); /* flush buffered data */
}
sim_activate_after(uptr, 1000000); /* check again in 1 second */
@ -739,7 +749,8 @@ return stat;
static void _sim_rem_log_out (TMLN *lp)
{
char cbuf[4*CBUFSIZE];
int line = (int)(lp - sim_rem_con_tmxr.ldsc);
REMOTE *rem = &sim_rem_consoles[(int)(lp - sim_rem_con_tmxr.ldsc)];
int line = rem->line;
if ((!sim_oline) && (sim_log)) {
fflush (sim_log);
@ -749,7 +760,7 @@ if ((!sim_oline) && (sim_log)) {
tmxr_linemsgf (lp, "%s", cbuf);
}
sim_oline = NULL;
if ((sim_rem_act[line] == NULL) &&
if ((rem->act == NULL) &&
(!tmxr_input_pending_ln (lp))) {
int32 unwritten;
@ -795,10 +806,10 @@ sim_switches = saved_switches; /* restore original switches */
static char *sim_rem_clract (int32 line)
{
TMLN *lp = &sim_rem_con_tmxr.ldsc[line];
REMOTE *rem = &sim_rem_consoles[line];
tmxr_send_buffered_data (lp); /* flush any buffered data */
return sim_rem_act[line] = NULL;
tmxr_send_buffered_data (rem->lp); /* flush any buffered data */
return rem->act = NULL;
}
/* Set up pending actions */
@ -807,13 +818,14 @@ static void sim_rem_setact (int32 line, const char *action)
{
if (action) {
size_t act_size = strlen (action) + 1;
REMOTE *rem = &sim_rem_consoles[line];
if (act_size > sim_rem_act_buf_size[line]) {/* expand buffer if necessary */
sim_rem_act_buf[line] = (char *)realloc (sim_rem_act_buf[line], act_size);
sim_rem_act_buf_size[line] = act_size;
if (act_size > rem->act_buf_size) { /* expand buffer if necessary */
rem->act_buf = (char *)realloc (rem->act_buf, act_size);
rem->act_buf_size = act_size;
}
strcpy (sim_rem_act_buf[line], action); /* populate buffer */
sim_rem_act[line] = sim_rem_act_buf[line]; /* start at beginning of buffer */
strcpy (rem->act_buf, action); /* populate buffer */
rem->act = rem->act_buf; /* start at beginning of buffer */
}
else
sim_rem_clract (line);
@ -825,22 +837,23 @@ static char *sim_rem_getact (int32 line, char *buf, int32 size)
{
char *ep;
size_t lnt;
REMOTE *rem = &sim_rem_consoles[line];
if (sim_rem_act[line] == NULL) /* any action? */
if (rem->act == NULL) /* any action? */
return NULL;
while (sim_isspace (*sim_rem_act[line])) /* skip spaces */
sim_rem_act[line]++;
if (*sim_rem_act[line] == 0) /* now empty? */
while (sim_isspace (*rem->act)) /* skip spaces */
rem->act++;
if (*rem->act == 0) /* now empty? */
return sim_rem_clract (line);
if ((ep = strchr (sim_rem_act[line], ';'))) { /* cmd delimiter? */
lnt = ep - sim_rem_act[line]; /* cmd length */
memcpy (buf, sim_rem_act[line], lnt + 1); /* copy with ; */
if ((ep = strchr (rem->act, ';'))) { /* cmd delimiter? */
lnt = ep - rem->act; /* cmd length */
memcpy (buf, rem->act, lnt + 1); /* copy with ; */
buf[lnt] = 0; /* erase ; */
sim_rem_act[line] += lnt + 1; /* adv ptr */
rem->act += lnt + 1; /* adv ptr */
}
else {
strncpy (buf, sim_rem_act[line], size); /* copy action */
sim_rem_act[line] += strlen (sim_rem_act[line]);/* adv ptr to end */
strncpy (buf, rem->act, size); /* copy action */
rem->act += strlen (rem->act); /* adv ptr to end */
}
return buf;
}
@ -856,6 +869,7 @@ int32 val;
t_bool all_stop = FALSE;
t_stat stat = SCPE_OK;
CONST char *cptr = *iptr;
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_REP, &sim_remote_console, "Repeat Setup: %s\n", cptr);
if (*cptr == 0) /* required argument? */
@ -872,7 +886,7 @@ else {
if ((MATCH_CMD (gbuf, "USECS") != 0) || (*cptr == 0))
stat = SCPE_ARG;
else
sim_rem_repeat_interval[line] = val;
rem->repeat_interval = val;
}
}
else {
@ -887,7 +901,7 @@ else {
all_stop = TRUE;
}
else
sim_rem_repeat_interval[line] = 0;
rem->repeat_interval = 0;
}
else
stat = SCPE_ARG;
@ -896,26 +910,27 @@ else {
if (stat == SCPE_OK) {
if (all_stop) {
for (line = 0; line < sim_rem_con_tmxr.lines; line++) {
free (sim_rem_repeat_action[line]);
sim_rem_repeat_action[line] = NULL;
sim_cancel (&sim_rem_con_unit[line + 2]);
sim_rem_repeat_pending[line] = FALSE;
rem = &sim_rem_consoles[line];
free (rem->repeat_action);
rem->repeat_action = NULL;
sim_cancel (rem->uptr);
rem->repeat_pending = FALSE;
sim_rem_clract (line);
}
}
else {
if (sim_rem_repeat_interval[line] != 0) {
sim_rem_repeat_action[line] = (char *)realloc (sim_rem_repeat_action[line], 1 + strlen (cptr));
strcpy (sim_rem_repeat_action[line], cptr);
if (rem->repeat_interval != 0) {
rem->repeat_action = (char *)realloc (rem->repeat_action, 1 + strlen (cptr));
strcpy (rem->repeat_action, cptr);
cptr += strlen (cptr);
stat = sim_activate_after (&sim_rem_con_unit[line + 2], sim_rem_repeat_interval[line]);
stat = sim_activate_after (rem->uptr, rem->repeat_interval);
}
else {
free (sim_rem_repeat_action[line]);
sim_rem_repeat_action[line] = NULL;
sim_cancel (&sim_rem_con_unit[line + 2]);
free (rem->repeat_action);
rem->repeat_action = NULL;
sim_cancel (rem->uptr);
}
sim_rem_repeat_pending[line] = FALSE;
rem->repeat_pending = FALSE;
sim_rem_clract (line);
}
}
@ -945,11 +960,12 @@ tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */
for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
(i < sim_rem_con_tmxr.lines) && (!active_command);
i++) {
REMOTE *rem = &sim_rem_consoles[i];
t_bool master_session = (sim_rem_master_mode && (i == 0));
lp = &sim_rem_con_tmxr.ldsc[i];
lp = rem->lp;
if (!lp->conn) {
if (sim_rem_repeat_interval[i]) { /* was repeated enabled? */
if (rem->repeat_interval) { /* was repeated enabled? */
cptr = strcpy (gbuf, "STOP");
_rem_repeat_cmd_setup (i, &cptr); /* make sure it is now disabled */
}
@ -962,8 +978,8 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
sim_rem_master_was_connected |= master_session; /* Remember if master ever connected */
stat = SCPE_OK;
if ((was_active_command) ||
(master_session && !sim_rem_single_mode[i])) {
sim_debug (DBG_MOD, &sim_remote_console, "Session: %d %s %s\n", i, was_active_command ? "Was Active" : "", (master_session && !sim_rem_single_mode[i]) ? "master_session && !sim_rem_single_mode[i]" : "");
(master_session && !rem->single_mode)) {
sim_debug (DBG_MOD, &sim_remote_console, "Session: %d %s %s\n", i, was_active_command ? "Was Active" : "", (master_session && !rem->single_mode) ? "master_session && !single_mode" : "");
if (was_active_command) {
sim_rem_cmd_active_line = -1; /* Done with active command */
if (!sim_rem_active_command) { /* STEP command? */
@ -989,14 +1005,14 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
}
}
else {
if ((!sim_rem_repeat_pending[i]) || (sim_rem_buf_ptr[i] != 0)) {
if ((!rem->repeat_pending) || (rem->buf_ptr != 0)) {
c = tmxr_getc_ln (lp);
if (!(TMXR_VALID & c))
continue;
c = c & ~TMXR_VALID;
if (sim_rem_single_mode[i]) {
if (rem->single_mode) {
if (c == sim_int_char) { /* ^E (the interrupt character) must start continue mode console interaction */
sim_rem_single_mode[i] = FALSE; /* enter multi command mode */
rem->single_mode = FALSE; /* enter multi command mode */
sim_is_running = 0;
sim_stop_timer_services ();
stat = SCPE_STOP;
@ -1012,14 +1028,14 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
lp = &sim_rem_con_tmxr.ldsc[i];
if (!master_session)
tmxr_linemsg (lp, "\r\nSimulator paused.\r\n");
if (!master_session && sim_rem_read_timeouts[i]) {
if (!master_session && rem->read_timeout) {
tmxr_linemsgf (lp, "Simulation will resume automatically if input is not received in %d seconds\n", sim_rem_read_timeouts[i]);
tmxr_linemsgf (lp, "\r\n");
tmxr_send_buffered_data (lp); /* flush any buffered data */
}
}
else {
if ((sim_rem_buf_ptr[i] == 0) && /* At beginning of input line */
if ((rem->buf_ptr == 0) && /* At beginning of input line */
((c == '\n') || /* Ignore bare LF between commands (Microsoft Telnet bug) */
(c == '\r'))) /* Ignore empty commands */
continue;
@ -1029,14 +1045,14 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
tmxr_reset_ln (lp);
continue;
}
if (sim_rem_buf_ptr[i] == 0) {
if (rem->buf_ptr == 0) {
/* we just picked up the first character on a command line */
if (!master_session)
tmxr_linemsgf (lp, "\r\n%s", sim_prompt);
else
tmxr_linemsgf (lp, "\r\n%s", sim_is_running ? "SIM> " : "sim> ");
sim_debug (DBG_XMT, &sim_remote_console, "Prompt Written: %s\n", sim_is_running ? "SIM> " : "sim> ");
if ((sim_rem_act[i] == NULL) && (!tmxr_input_pending_ln (lp)))
if ((rem->act == NULL) && (!tmxr_input_pending_ln (lp)))
tmxr_send_buffered_data (lp);/* flush any buffered data */
}
}
@ -1047,7 +1063,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
while (1) {
if (stat == SCPE_EXIT)
return stat|SCPE_NOMESSAGE;
if (!sim_rem_single_mode[i]) {
if (!rem->single_mode) {
read_start_time = sim_os_msec();
if (master_session)
tmxr_linemsg (lp, "sim> ");
@ -1056,55 +1072,55 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
tmxr_send_buffered_data (lp); /* flush any buffered data */
}
do {
if (sim_rem_buf_ptr[i] == 0) {
if (sim_rem_getact (i, sim_rem_buf[i], sim_rem_buf_size[i])) {
if (rem->buf_ptr == 0) {
if (sim_rem_getact (i, rem->buf, rem->buf_size)) {
if (!master_session)
tmxr_linemsgf (lp, "%s%s\n", sim_prompt, sim_rem_buf[i]);
tmxr_linemsgf (lp, "%s%s\n", sim_prompt, rem->buf);
else
tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", sim_rem_buf[i]);
sim_rem_buf_ptr[i] = strlen (sim_rem_repeat_action[i]);
tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", rem->buf);
rem->buf_ptr = strlen (rem->repeat_action);
got_command = TRUE;
break;
}
else {
if (sim_rem_repeat_pending[i]) {
sim_rem_repeat_pending[i] = FALSE;
sim_rem_setact (i, sim_rem_repeat_action[i]);
sim_rem_getact (i, sim_rem_buf[i], sim_rem_buf_size[i]);
if (rem->repeat_pending) {
rem->repeat_pending = FALSE;
sim_rem_setact (i, rem->repeat_action);
sim_rem_getact (i, rem->buf, rem->buf_size);
if (!master_session)
tmxr_linemsgf (lp, "%s%s\n", sim_prompt, sim_rem_buf[i]);
tmxr_linemsgf (lp, "%s%s\n", sim_prompt, rem->buf);
else
tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", sim_rem_buf[i]);
sim_rem_buf_ptr[i] = strlen (sim_rem_repeat_action[i]);
tmxr_linemsgf (lp, "%s%s\n", sim_is_running ? "SIM> " : "sim> ", rem->buf);
rem->buf_ptr = strlen (rem->repeat_action);
got_command = TRUE;
break;
}
}
}
if (!sim_rem_single_mode[i]) {
if (!rem->single_mode) {
c = tmxr_getc_ln (lp);
if (!(TMXR_VALID & c)) {
tmxr_send_buffered_data (lp); /* flush any buffered data */
if (!master_session &&
sim_rem_read_timeouts[i] &&
((sim_os_msec() - read_start_time)/1000 >= sim_rem_read_timeouts[i])) {
while (sim_rem_buf_ptr[i] > 0) {/* Erase current input line */
rem->read_timeout &&
((sim_os_msec() - read_start_time)/1000 >= rem->read_timeout)) {
while (rem->buf_ptr > 0) { /* Erase current input line */
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
--rem->buf_ptr;
}
if (sim_rem_buf_ptr[i]+80 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = (char *)realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
if (rem->buf_ptr+80 >= rem->buf_size) {
rem->buf_size += 1024;
rem->buf = (char *)realloc (rem->buf, rem->buf_size);
}
strcpy (sim_rem_buf[i], "CONTINUE ! Automatic continue due to timeout");
tmxr_linemsgf (lp, "%s\n", sim_rem_buf[i]);
strcpy (rem->buf, "CONTINUE ! Automatic continue due to timeout");
tmxr_linemsgf (lp, "%s\n", rem->buf);
got_command = TRUE;
break;
}
sim_os_ms_sleep (50);
tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */
if (!lp->conn) { /* if connection lost? */
sim_rem_single_mode[i] = TRUE; /* No longer multi-command more */
rem->single_mode = TRUE; /* No longer multi-command more */
break; /* done waiting */
}
continue;
@ -1117,88 +1133,88 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
break;
case '\b': /* Backspace */
case 127: /* Rubout */
if (sim_rem_buf_ptr[i] > 0) {
if (rem->buf_ptr > 0) {
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
--rem->buf_ptr;
}
break;
case 27: /* escape */
case 21: /* ^U */
while (sim_rem_buf_ptr[i] > 0) {
while (rem->buf_ptr > 0) {
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
--rem->buf_ptr;
}
break;
case '\n':
if (sim_rem_buf_ptr[i] == 0)
if (rem->buf_ptr == 0)
break;
case '\r':
tmxr_linemsg (lp, "\r\n");
if (sim_rem_buf_ptr[i]+1 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = (char *)realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
if (rem->buf_ptr+1 >= rem->buf_size) {
rem->buf_size += 1024;
rem->buf = (char *)realloc (rem->buf, rem->buf_size);
}
sim_rem_buf[i][sim_rem_buf_ptr[i]++] = '\0';
sim_debug (DBG_RCV, &sim_remote_console, "Got Command (%d bytes still in buffer): %s\n", tmxr_input_pending_ln (lp), sim_rem_buf[i]);
rem->buf[rem->buf_ptr++] = '\0';
sim_debug (DBG_RCV, &sim_remote_console, "Got Command (%d bytes still in buffer): %s\n", tmxr_input_pending_ln (lp), rem->buf);
got_command = TRUE;
break;
case '\004': /* EOF (^D) */
case '\032': /* EOF (^Z) */
while (sim_rem_buf_ptr[i] > 0) { /* Erase current input line */
while (rem->buf_ptr > 0) { /* Erase current input line */
tmxr_linemsg (lp, "\b \b");
--sim_rem_buf_ptr[i];
--rem->buf_ptr;
}
if (!sim_rem_single_mode[i]) {
if (sim_rem_buf_ptr[i]+80 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = (char *)realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
if (!rem->single_mode) {
if (rem->buf_ptr+80 >= rem->buf_size) {
rem->buf_size += 1024;
rem->buf = (char *)realloc (rem->buf, rem->buf_size);
}
strcpy (sim_rem_buf[i], "CONTINUE ! Automatic continue before close");
tmxr_linemsgf (lp, "%s\n", sim_rem_buf[i]);
strcpy (rem->buf, "CONTINUE ! Automatic continue before close");
tmxr_linemsgf (lp, "%s\n", rem->buf);
got_command = TRUE;
}
close_session = TRUE;
break;
default:
tmxr_putc_ln (lp, c);
if (sim_rem_buf_ptr[i]+2 >= sim_rem_buf_size[i]) {
sim_rem_buf_size[i] += 1024;
sim_rem_buf[i] = (char *)realloc (sim_rem_buf[i], sim_rem_buf_size[i]);
if (rem->buf_ptr+2 >= rem->buf_size) {
rem->buf_size += 1024;
rem->buf = (char *)realloc (rem->buf, rem->buf_size);
}
sim_rem_buf[i][sim_rem_buf_ptr[i]++] = (char)c;
sim_rem_buf[i][sim_rem_buf_ptr[i]] = '\0';
if (((size_t)sim_rem_buf_ptr[i]) >= sizeof(cbuf))
rem->buf[rem->buf_ptr++] = (char)c;
rem->buf[rem->buf_ptr] = '\0';
if (((size_t)rem->buf_ptr) >= sizeof(cbuf))
got_command = TRUE; /* command too long */
break;
}
c = 0;
if ((!got_command) && (sim_rem_single_mode[i]) && (tmxr_input_pending_ln (lp))) {
if ((!got_command) && (rem->single_mode) && (tmxr_input_pending_ln (lp))) {
c = tmxr_getc_ln (lp);
c = c & ~TMXR_VALID;
}
} while ((!got_command) && ((!sim_rem_single_mode[i]) || c));
if ((sim_rem_act[i] == NULL) && (!tmxr_input_pending_ln (lp)))
} while ((!got_command) && ((!rem->single_mode) || c));
if ((rem->act == NULL) && (!tmxr_input_pending_ln (lp)))
tmxr_send_buffered_data (lp); /* flush any buffered data */
if ((sim_rem_single_mode[i]) && !got_command) {
if ((rem->single_mode) && !got_command) {
break;
}
if (!sim_rem_master_mode)
sim_printf ("Remote Console Command from %s> %s\r\n", lp->ipad, sim_rem_buf[i]);
sim_printf ("Remote Console Command from %s> %s\r\n", lp->ipad, rem->buf);
got_command = FALSE;
if (strlen(sim_rem_buf[i]) >= sizeof(cbuf)) {
if (strlen(rem->buf) >= sizeof(cbuf)) {
sim_printf ("\r\nLine too long. Ignored. Continuing Simulator execution\r\n");
tmxr_linemsgf (lp, "\nLine too long. Ignored. Continuing Simulator execution\n");
tmxr_send_buffered_data (lp); /* try to flush any buffered data */
break;
}
strcpy (cbuf, sim_rem_buf[i]);
sim_rem_buf_ptr[i] = 0;
sim_rem_buf[i][sim_rem_buf_ptr[i]] = '\0';
strcpy (cbuf, rem->buf);
rem->buf_ptr = 0;
rem->buf[rem->buf_ptr] = '\0';
while (isspace(cbuf[0]))
memmove (cbuf, cbuf+1, strlen(cbuf+1)+1); /* skip leading whitespace */
if (cbuf[0] == '\0') {
if (sim_rem_single_mode[i]) {
sim_rem_single_mode[i] = FALSE;
if (rem->single_mode) {
rem->single_mode = FALSE;
break;
}
else
@ -1235,7 +1251,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
stat = SCPE_UNK;
}
else {
if ((cmdp = find_ctab (sim_rem_single_mode[i] ? allowed_single_remote_cmds : (master_session ? allowed_master_remote_cmds : allowed_remote_cmds), gbuf))) {/* lookup command */
if ((cmdp = find_ctab (rem->single_mode ? allowed_single_remote_cmds : (master_session ? allowed_master_remote_cmds : allowed_remote_cmds), gbuf))) {/* lookup command */
sim_debug (DBG_CMD, &sim_remote_console, "gbuf='%s', basecmd='%s', cmd='%s', action=%p, continue_cmd=%p, repeat_cmd=%p\n", gbuf, basecmdp->name, cmdp->name, cmdp->action, &x_continue_cmd, &x_repeat_cmd);
if (cmdp->action == &x_continue_cmd) {
sim_debug (DBG_CMD, &sim_remote_console, "continue_cmd executing\n");
@ -1305,7 +1321,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
stat = _sim_rem_message (gbuf, stat);
_sim_rem_log_out (lp);
if (master_session && !sim_rem_master_mode) {
sim_rem_single_mode[i] = TRUE;
rem->single_mode = TRUE;
return SCPE_STOP;
}
if (cmdp && (cmdp->action == &x_continue_cmd)) {
@ -1324,7 +1340,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
fflush (sim_log);
sim_rem_cmd_log_start = sim_ftell (sim_log);
}
if (!sim_rem_single_mode[i]) {
if (!rem->single_mode) {
tmxr_linemsg (lp, "Simulator Running...");
tmxr_send_buffered_data (lp);
for (j=0; j < sim_rem_con_tmxr.lines; j++) {
@ -1338,9 +1354,9 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
sim_start_timer_services ();
}
if (cmdp && (cmdp->action == &x_continue_cmd))
sim_rem_single_mode[i] = TRUE;
rem->single_mode = TRUE;
else {
if (!sim_rem_single_mode[i]) {
if (!rem->single_mode) {
if (master_session)
tmxr_linemsgf (lp, "%s", "sim> ");
else
@ -1360,7 +1376,7 @@ for (i=(was_active_command ? sim_rem_cmd_active_line : 0);
tmxr_linemsgf (lp, "\r\nGoodbye\r\n");
tmxr_send_buffered_data (lp); /* flush any buffered data */
tmxr_reset_ln (lp);
sim_rem_single_mode[i] = FALSE;
rem->single_mode = FALSE;
}
}
if (sim_rem_master_was_connected && /* Master mode ever connected? */
@ -1387,11 +1403,12 @@ else
t_stat sim_rem_con_repeat_svc (UNIT *uptr)
{
int line = uptr - (sim_rem_con_unit + 2);
REMOTE *rem = &sim_rem_consoles[line];
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%d) - interval=%d\n", line, sim_rem_repeat_interval[line]);
if (sim_rem_repeat_interval[line]) {
sim_rem_repeat_pending[line] = TRUE;
sim_activate_after (uptr, sim_rem_repeat_interval[line]); /* reschedule */
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_repeat_svc(line=%d) - interval=%d\n", line, rem->repeat_interval);
if (rem->repeat_interval) {
rem->repeat_pending = TRUE;
sim_activate_after (uptr, rem->repeat_interval); /* reschedule */
sim_activate_abs (&sim_rem_con_unit[1], -1); /* wake up to process */
}
return SCPE_OK;
@ -1408,11 +1425,13 @@ if (sim_rem_con_tmxr.lines) {
sim_rem_con_unit[i + 2].action = &sim_rem_con_repeat_svc;
}
for (i=0; i<sim_rem_con_tmxr.lines; i++) {
REMOTE *rem = &sim_rem_consoles[i];
if (!sim_rem_con_tmxr.ldsc[i].conn)
continue;
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_reset(line=%d, usecs=%d)\n", i, sim_rem_repeat_interval[i]);
if (sim_rem_repeat_interval[i])
sim_activate_after (sim_rem_con_unit + 2 + i, sim_rem_repeat_interval[i]);/* schedule */
sim_debug (DBG_REP, &sim_remote_console, "sim_rem_con_reset(line=%d, usecs=%d)\n", i, rem->repeat_interval);
if (rem->repeat_interval)
sim_activate_after (sim_rem_con_unit + 2 + i, rem->repeat_interval);/* schedule */
}
if (i != sim_rem_con_tmxr.lines)
sim_activate_after (&dptr->units[1], 100000); /* continue polling for open sessions */
@ -1447,11 +1466,12 @@ else {
tmxr_detach (&sim_rem_con_tmxr, &sim_rem_con_unit[0]);
for (i=0; i<sim_rem_con_tmxr.lines; i++) {
free (sim_rem_buf[i]);
sim_rem_buf[i] = NULL;
sim_rem_buf_size[i] = 0;
sim_rem_buf_ptr[i] = 0;
sim_rem_single_mode[i] = TRUE;
REMOTE *rem = &sim_rem_consoles[i];
free (rem->buf);
rem->buf = NULL;
rem->buf_size = 0;
rem->buf_ptr = 0;
rem->single_mode = TRUE;
}
}
}
@ -1461,6 +1481,7 @@ return SCPE_OK;
static t_stat sim_set_rem_connections (int32 flag, CONST char *cptr)
{
int32 lines;
REMOTE *rem;
t_stat r;
int32 i;
@ -1470,36 +1491,27 @@ lines = (int32) get_uint (cptr, 10, MAX_REMOTE_SESSIONS, &r);
if (r != SCPE_OK)
return r;
if (sim_rem_con_tmxr.master)
return SCPE_ARG;
for (i=0; i<sim_rem_con_tmxr.lines; i++)
free (sim_rem_buf[i]);
return SCPE_ALATT;
for (i=0; i<sim_rem_con_tmxr.lines; i++) {
rem = &sim_rem_consoles[i];
free (rem->buf);
free (rem->act_buf);
free (rem->act);
free (rem->repeat_action);
}
sim_rem_con_tmxr.lines = lines;
sim_rem_con_tmxr.ldsc = (TMLN *)realloc (sim_rem_con_tmxr.ldsc, sizeof(*sim_rem_con_tmxr.ldsc)*lines);
memset (sim_rem_con_tmxr.ldsc, 0, sizeof(*sim_rem_con_tmxr.ldsc)*lines);
sim_rem_buf = (char **)realloc (sim_rem_buf, sizeof(*sim_rem_buf)*lines);
memset (sim_rem_buf, 0, sizeof(*sim_rem_buf)*lines);
sim_rem_act_buf = (char **)realloc (sim_rem_act_buf, sizeof(*sim_rem_act_buf)*lines);
memset (sim_rem_act_buf, 0, sizeof(*sim_rem_act_buf)*lines);
sim_rem_act_buf_size = (size_t *)realloc (sim_rem_act_buf_size, sizeof(*sim_rem_act_buf_size)*lines);
memset (sim_rem_act_buf_size, 0, sizeof(*sim_rem_act_buf_size)*lines);
sim_rem_act = (char **)realloc (sim_rem_act, sizeof(*sim_rem_act)*lines);
memset (sim_rem_act, 0, sizeof(*sim_rem_act)*lines);
sim_rem_buf_size = (int32 *)realloc (sim_rem_buf_size, sizeof(*sim_rem_buf_size)*lines);
memset (sim_rem_buf_size, 0, sizeof(*sim_rem_buf_size)*lines);
sim_rem_buf_ptr = (int32 *)realloc (sim_rem_buf_ptr, sizeof(*sim_rem_buf_ptr)*lines);
memset (sim_rem_buf_ptr, 0, sizeof(*sim_rem_buf_ptr)*lines);
sim_rem_repeat_interval = (uint32 *)realloc (sim_rem_repeat_interval, sizeof(*sim_rem_repeat_interval)*lines);
memset (sim_rem_repeat_interval, 0, sizeof(*sim_rem_repeat_interval)*lines);
sim_rem_repeat_pending = (t_bool *)realloc (sim_rem_repeat_pending, sizeof(*sim_rem_repeat_pending)*lines);
memset (sim_rem_repeat_pending, 0, sizeof(*sim_rem_repeat_pending)*lines);
sim_rem_repeat_action = (char **)realloc (sim_rem_repeat_action, sizeof(*sim_rem_repeat_action)*lines);
memset (sim_rem_repeat_action, 0, sizeof(*sim_rem_repeat_action)*lines);
sim_rem_single_mode = (t_bool *)realloc (sim_rem_single_mode, sizeof(*sim_rem_single_mode)*lines);
memset (sim_rem_single_mode, 0, sizeof(*sim_rem_single_mode)*lines);
sim_rem_read_timeouts = (uint32 *)realloc (sim_rem_read_timeouts, sizeof(*sim_rem_read_timeouts)*lines);
memset (sim_rem_read_timeouts, 0, sizeof(*sim_rem_read_timeouts)*lines);
sim_rem_consoles = (REMOTE *)realloc (sim_rem_consoles, sizeof(*sim_rem_consoles)*lines);
memset (sim_rem_consoles, 0, sizeof(*sim_rem_consoles)*lines);
sim_rem_command_buf = (char *)realloc (sim_rem_command_buf, 4*CBUFSIZE+1);
memset (sim_rem_command_buf, 0, 4*CBUFSIZE+1);
for (i=0; i<sim_rem_con_tmxr.lines; i++) {
rem = &sim_rem_consoles[i];
rem->line = i;
rem->lp = &sim_rem_con_tmxr.ldsc[i];
rem->uptr = &sim_rem_con_unit[i + 2];
}
return SCPE_OK;
}
@ -1514,7 +1526,7 @@ timeout = (int32) get_uint (cptr, 10, 3600, &r);
if (r != SCPE_OK)
return r;
if (sim_rem_active_number >= 0)
sim_rem_read_timeouts[sim_rem_active_number] = timeout;
sim_rem_consoles[sim_rem_active_number].read_timeout = timeout;
else
sim_rem_read_timeout = timeout;
return SCPE_OK;
@ -1571,7 +1583,7 @@ if (sim_rem_master_mode) {
stat = sim_run_boot_prep (0);
sim_rem_master_was_enabled = TRUE;
while (sim_rem_master_mode) {
sim_rem_single_mode[0] = FALSE;
sim_rem_consoles[0].single_mode = FALSE;
sim_cancel (&sim_rem_con_unit[1]);
sim_activate (&sim_rem_con_unit[1], -1);
stat = run_cmd (RU_GO, "");
@ -1596,9 +1608,8 @@ if (sim_rem_master_mode) {
stat |= stat_nomessage;
}
else {
sim_rem_single_mode[0] = TRUE; /* Force remote session into single command mode */
sim_rem_consoles[0].single_mode = TRUE; /* Force remote session into single command mode */
}
return stat;
}