diff --git a/scp.c b/scp.c index 13adfd87..6bd13f90 100644 --- a/scp.c +++ b/scp.c @@ -351,8 +351,6 @@ t_stat set_dev_enbdis (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat set_dev_debug (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat set_unit_enbdis (DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat ssh_break (FILE *st, char *cptr, int32 flg); -t_stat set_default_cmd (int32 flg, char *cptr); -t_stat pwd_cmd (int32 flg, char *cptr); t_stat show_cmd_fi (FILE *ofile, int32 flag, char *cptr); t_stat show_config (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat show_queue (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); @@ -432,7 +430,6 @@ t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr, UNIT *uptr, int32 dfltinc); void fprint_fields (FILE *stream, t_value before, t_value after, BITFIELD* bitdefs); t_stat step_svc (UNIT *ptr); -void sub_args (char *instr, size_t instr_size, char *do_arg[]); t_stat shift_args (char *do_arg[], size_t arg_count); t_stat set_on (int32 flag, char *cptr); t_stat set_verify (int32 flag, char *cptr); @@ -564,6 +561,7 @@ const struct scp_error { {"TTMO", "Console Telnet connection timed out"}, {"STALL", "Console Telnet output stall"}, {"AFAIL", "Assertion failed"}, + {"INVREM", "Invalid remote console command"}, }; const size_t size_map[] = { sizeof (int8), @@ -676,6 +674,9 @@ static CTAB cmd_table[] = { " specified destination {STDOUT,STDERR,DEBUG\n" " or filename)\n" "set console NOLOG disable console logging\n" + "set remote TELNET=port specify remote console telnet port\n" + "set remote NOTELNET disables remote console\n" + "set remote CONNECTIONS=n specify number of concurrent remote console sessions\n" "set default set the current directory\n" "set log log_file specify the log destination\n" " (STDOUT,DEBUG or filename)\n" @@ -729,6 +730,7 @@ static CTAB cmd_table[] = { "sh{ow} a{synch} show asynchronouse I/O state\n" "sh{ow} ve{rsion} show simulator version\n" "sh{ow} def{ault} show current directory\n" + "sh{ow} rem{oteconsole} show remote console configuration\n" "sh{ow} RADIX show device display radix\n" "sh{ow} DEBUG show device debug flags\n" "sh{ow} MODIFIERS show device modifiers\n" @@ -927,7 +929,7 @@ while (stat != SCPE_EXIT) { /* in case exit */ } if (*cptr == 0) /* ignore blank */ continue; - sub_args (cbuf, sizeof(cbuf), argv); + sim_sub_args (cbuf, sizeof(cbuf), argv); if (sim_log) /* log cmd */ fprintf (sim_log, "%s%s\n", sim_prompt, cptr); cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */ @@ -1574,7 +1576,7 @@ do { ocptr = cptr = read_line (cbuf, sizeof(cbuf), fpin);/* get cmd line */ sim_goto_line[sim_do_depth] += 1; } - sub_args (cbuf, sizeof(cbuf), do_arg); /* substitute args */ + sim_sub_args (cbuf, sizeof(cbuf), do_arg); /* substitute args */ if (cptr == NULL) { /* EOF? */ stat = SCPE_OK; /* set good return */ break; @@ -1733,7 +1735,7 @@ return stat | SCPE_NOMESSAGE; /* suppress message sinc untouched. */ -void sub_args (char *instr, size_t instr_size, char *do_arg[]) +void sim_sub_args (char *instr, size_t instr_size, char *do_arg[]) { char gbuf[CBUFSIZE]; char *ip = instr, *op, *ap, *oend, *istart, *tmpbuf; @@ -2207,6 +2209,7 @@ C1TAB *ctbr, *glbr; static CTAB set_glob_tab[] = { { "CONSOLE", &sim_set_console, 0 }, + { "REMOTE", &sim_set_remote_console, 0 }, { "BREAK", &brk_cmd, SSH_ST }, { "DEFAULT", &set_default_cmd, 1 }, { "NOBREAK", &brk_cmd, SSH_CL }, @@ -2505,6 +2508,7 @@ static SHTAB show_glob_tab[] = { { "VERSION", &show_version, 1 }, { "DEFAULT", &show_default, 0 }, { "CONSOLE", &sim_show_console, 0 }, + { "REMOTE", &sim_show_remote_console, 0 }, { "BREAK", &show_break, 0 }, { "LOG", &sim_show_log, 0 }, /* deprecated */ { "TELNET", &sim_show_telnet, 0 }, /* deprecated */ diff --git a/scp.h b/scp.h index 8bf399b4..317081e7 100644 --- a/scp.h +++ b/scp.h @@ -69,6 +69,8 @@ t_stat restore_cmd (int32 flag, char *ptr); t_stat exit_cmd (int32 flag, char *ptr); t_stat set_cmd (int32 flag, char *ptr); t_stat show_cmd (int32 flag, char *ptr); +t_stat set_default_cmd (int32 flg, char *cptr); +t_stat pwd_cmd (int32 flg, char *cptr); t_stat brk_cmd (int32 flag, char *ptr); t_stat do_cmd (int32 flag, char *ptr); t_stat goto_cmd (int32 flag, char *ptr); @@ -122,6 +124,7 @@ DEVICE *find_dev (char *ptr); DEVICE *find_unit (char *ptr, UNIT **uptr); DEVICE *find_dev_from_unit (UNIT *uptr); t_stat sim_register_internal_device (DEVICE *dptr); +void sim_sub_args (char *in_str, size_t in_str_size, char *do_arg[]); REG *find_reg (char *ptr, char **optr, DEVICE *dptr); CTAB *find_ctab (CTAB *tab, char *gbuf); C1TAB *find_c1tab (C1TAB *tab, char *gbuf); diff --git a/sim_console.c b/sim_console.c index 2ed8f473..749ec909 100644 --- a/sim_console.c +++ b/sim_console.c @@ -125,14 +125,17 @@ /* Forward Declaraations of Platform specific routines */ -t_stat sim_os_poll_kbd (void); -t_bool sim_os_poll_kbd_ready (int ms_timeout); -t_stat sim_os_putchar (int32 out); -t_stat sim_os_ttinit (void); -t_stat sim_os_ttrun (void); -t_stat sim_os_ttcmd (void); -t_stat sim_os_ttclose (void); -t_bool sim_os_ttisatty (void); +static t_stat sim_os_poll_kbd (void); +static t_bool sim_os_poll_kbd_ready (int ms_timeout); +static t_stat sim_os_putchar (int32 out); +static t_stat sim_os_ttinit (void); +static t_stat sim_os_ttrun (void); +static t_stat sim_os_ttcmd (void); +static t_stat sim_os_ttclose (void); +static t_bool sim_os_ttisatty (void); + +static t_stat sim_set_rem_telnet (int32 flag, char *cptr); +static t_stat sim_set_rem_connections (int32 flag, char *cptr); #define KMAP_WRU 0 #define KMAP_BRK 1 @@ -148,8 +151,8 @@ int32 sim_del_char = '\b'; /* delete character */ #else int32 sim_del_char = 0177; #endif -t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */ -t_stat sim_con_reset (DEVICE *dptr); /* console connection poll routine */ +static t_stat sim_con_poll_svc (UNIT *uptr); /* console connection poll routine */ +static t_stat sim_con_reset (DEVICE *dptr); /* console reset routine */ UNIT sim_con_unit = { UDATA (&sim_con_poll_svc, 0, 0) }; /* console connection unit */ /* debugging bitmaps */ #define DBG_TRC TMXR_DBG_TRC /* trace routine calls */ @@ -157,7 +160,7 @@ UNIT sim_con_unit = { UDATA (&sim_con_poll_svc, 0, 0) }; /* console connectio #define DBG_RCV TMXR_DBG_RCV /* display Received Data */ #define DBG_ASY TMXR_DBG_ASY /* asynchronous thread activity */ -DEBTAB sim_con_debug[] = { +static DEBTAB sim_con_debug[] = { {"TRC", DBG_TRC}, {"XMT", DBG_XMT}, {"RCV", DBG_RCV}, @@ -165,7 +168,7 @@ DEBTAB sim_con_debug[] = { {0} }; -MTAB sim_con_mod[] = { +static MTAB sim_con_mod[] = { { 0 }, }; @@ -179,7 +182,7 @@ TMXR sim_con_tmxr = { 1, 0, 0, &sim_con_ldsc, NULL, &sim_con_telnet };/* console /* Unit service for console connection polling */ -t_stat sim_con_poll_svc (UNIT *uptr) +static t_stat sim_con_poll_svc (UNIT *uptr) { if ((sim_con_tmxr.master == 0) && /* not Telnet and not serial? */ (sim_con_ldsc.serport == 0)) @@ -188,11 +191,11 @@ if (tmxr_poll_conn (&sim_con_tmxr) >= 0) /* poll connect */ sim_con_ldsc.rcve = 1; /* rcv enabled */ sim_activate_after(uptr, 1000000); /* check again in 1 second */ if (sim_con_ldsc.conn) - tmxr_send_buffered_data (&sim_con_ldsc); /* try to flush any buffered data */ + tmxr_send_buffered_data (&sim_con_ldsc); /* try to flush any buffered data */ return SCPE_OK; } -t_stat sim_con_reset (DEVICE *dptr) +static t_stat sim_con_reset (DEVICE *dptr) { return sim_con_poll_svc (&dptr->units[0]); /* establish polling as needed */ } @@ -216,6 +219,13 @@ static CTAB set_con_tab[] = { { NULL, NULL, 0 } }; +static CTAB set_rem_con_tab[] = { + { "CONNECTIONS", &sim_set_rem_connections, 0 }, + { "TELNET", &sim_set_rem_telnet, 1 }, + { "NOTELNET", &sim_set_rem_telnet, 0 }, + { NULL, NULL, 0 } + }; + static SHTAB show_con_tab[] = { { "WRU", &sim_show_kmap, KMAP_WRU }, { "BRK", &sim_show_kmap, KMAP_BRK }, @@ -304,6 +314,320 @@ while (*cptr != 0) { return SCPE_OK; } +t_stat sim_rem_con_poll_svc (UNIT *uptr); /* remote console connection poll routine */ +t_stat sim_rem_con_data_svc (UNIT *uptr); /* remote console connection data routine */ +t_stat sim_rem_con_reset (DEVICE *dptr); /* remote console reset routine */ +UNIT sim_rem_con_unit[2] = { + { UDATA (&sim_rem_con_poll_svc, 0, 0) }, /* remote console connection polling unit */ + { UDATA (&sim_rem_con_data_svc, 0, 0) }}; /* console data handling unit */ + +DEBTAB sim_rem_con_debug[] = { + {"TRC", DBG_TRC}, + {"XMT", DBG_XMT}, + {"RCV", DBG_RCV}, + {0} +}; + +MTAB sim_rem_con_mod[] = { + { 0 }, +}; + +DEVICE sim_remote_console = { + "REM-CON", sim_rem_con_unit, NULL, sim_rem_con_mod, + 2, 0, 0, 0, 0, 0, + NULL, NULL, sim_rem_con_reset, NULL, NULL, NULL, + NULL, DEV_DEBUG, 0, sim_rem_con_debug}; +int32 *sim_rem_buf_size = NULL; +int32 *sim_rem_buf_ptr = NULL; +char **sim_rem_buf = NULL; +TMXR sim_rem_con_tmxr = { 0, 0, 0, NULL, NULL, &sim_remote_console };/* remote console line mux */ + +/* SET REMOTE CONSOLE command */ + +t_stat sim_set_remote_console (int32 flag, char *cptr) +{ +char *cvptr, gbuf[CBUFSIZE]; +CTAB *ctptr; +t_stat r; + +if ((cptr == NULL) || (*cptr == 0)) + return SCPE_2FARG; +while (*cptr != 0) { /* do all mods */ + cptr = get_glyph_nc (cptr, gbuf, ','); /* get modifier */ + if ((cvptr = strchr (gbuf, '='))) /* = value? */ + *cvptr++ = 0; + get_glyph (gbuf, gbuf, 0); /* modifier to UC */ + if ((ctptr = find_ctab (set_rem_con_tab, gbuf))) { /* match? */ + r = ctptr->action (ctptr->arg, cvptr); /* do the rest */ + if (r != SCPE_OK) + return r; + } + else return SCPE_NOPARAM; + } +return SCPE_OK; +} + +/* SHOW REMOTE CONSOLE command */ + +t_stat sim_show_remote_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr) +{ +if (*cptr != 0) + return SCPE_NOPARAM; +if (!sim_rem_con_tmxr.master) { + fprintf (st, "Remote Console Command input is disabled\n"); + return SCPE_OK; + } +fprintf (st, "Remote Console Command Input listening on TCP port: %s\n", sim_rem_con_unit[0].filename); +if (sim_rem_con_tmxr.lines > 1) + fprintf (st, "Remote Console Input Connections from %d sources are supported concurrently\n", sim_rem_con_tmxr.lines); +return SCPE_OK; +} + +/* Unit service for remote console connection polling */ + +t_stat sim_rem_con_poll_svc (UNIT *uptr) +{ +int32 c; + +c = tmxr_poll_conn (&sim_rem_con_tmxr); +if (c >= 0) { /* poll connect */ + TMLN *lp = &sim_rem_con_tmxr.ldsc[c]; + + sim_activate_after(uptr+1, 1000000); /* start data poll after 100ms */ + lp->rcve = 1; /* rcv enabled */ + sim_rem_buf_ptr[c] = 0; /* start with empty command buffer */ + tmxr_linemsg (lp, sim_name); + tmxr_linemsg (lp, " Remote Console\r\nSimulator Running..."); + tmxr_send_buffered_data (lp); /* flush buffered data */ + } +sim_activate_after(uptr, 1000000); /* check again in 1 second */ +if (sim_con_ldsc.conn) + tmxr_send_buffered_data (&sim_con_ldsc); /* try to flush any buffered data */ +return SCPE_OK; +} + +static t_stat x_continue_cmd (int32 flag, char *cptr) +{ +return SCPE_IERR; /* This routine should never be called */ +} + +/* Unit service for remote console data polling */ + +t_stat sim_rem_con_data_svc (UNIT *uptr) +{ +int32 i, c; +t_stat stat, stat_nomessage; +t_bool got_command; +TMLN *lp; +char cbuf[4*CBUFSIZE], gbuf[CBUFSIZE], *cptr, *argv[1] = {NULL}; +CTAB *cmdp; +long cmd_log_start; +#define EX_D 0 /* deposit */ +#define EX_E 1 /* examine */ +#define EX_I 2 /* interactive */ +static CTAB allowed_remote_cmds[] = { + { "EXAMINE", &exdep_cmd, EX_E }, + { "IEXAMINE", &exdep_cmd, EX_E+EX_I }, + { "DEPOSIT", &exdep_cmd, EX_D }, + { "EVALUATE", &eval_cmd }, + { "ATTACH", &attach_cmd }, + { "DETACH", &detach_cmd }, + { "ASSIGN", &assign_cmd }, + { "DEASSIGN", &deassign_cmd }, + { "CONT", &x_continue_cmd }, + { "PROCEED", &noop_cmd }, + { "IGNORE", &noop_cmd }, + { "PWD", &pwd_cmd }, + { "SAVE", &save_cmd }, + { "SET", &save_cmd }, + { "SHOW", &show_cmd }, + { "ECHO", &echo_cmd }, + { "HELP", &help_cmd }, + { NULL, NULL } + }; + + +tmxr_poll_rx (&sim_rem_con_tmxr); /* poll input */ +for (i=0; i < sim_rem_con_tmxr.lines; i++) { + lp = &sim_rem_con_tmxr.ldsc[i]; + if (!lp->conn) + continue; + c = tmxr_getc_ln (lp); + if (!(TMXR_VALID & c)) + continue; + c = c & ~TMXR_VALID; + if (c != sim_int_char) + continue; /* ^E (the interrupt character) must start console interaction */ + tmxr_linemsg (lp, "\r\n"); + while (1) { + tmxr_linemsg (lp, "sim> "); + tmxr_send_buffered_data (lp); /* try to flush any buffered data */ + got_command = FALSE; + while (!got_command) { + c = tmxr_getc_ln (lp); + if (!(TMXR_VALID & c)) { + tmxr_send_buffered_data (lp); /* try to flush any buffered data */ + sim_os_ms_sleep (100); + tmxr_poll_rx (&sim_rem_con_tmxr);/* poll input */ + continue; + } + c = c & ~TMXR_VALID; + switch (c) { + case 0: /* no data */ + break; + case '\b': /* Backspace */ + case 127: /* Rubout */ + if (sim_rem_buf_ptr[i] > 0) { + tmxr_linemsg (lp, "\b \b"); + --sim_rem_buf_ptr[i]; + } + break; + case 27: /* escape */ + case 21: /* ^U */ + while (sim_rem_buf_ptr[i] > 0) { + tmxr_linemsg (lp, "\b \b"); + --sim_rem_buf_ptr[i]; + } + break; + case '\r': + tmxr_putc_ln (lp, c); + tmxr_putc_ln (lp, '\n'); + if (sim_rem_buf_ptr[i]+1 >= sim_rem_buf_size[i]) { + sim_rem_buf_size[i] += 1024; + sim_rem_buf[i] = realloc (sim_rem_buf[i], sim_rem_buf_size[i]); + } + sim_rem_buf[i][sim_rem_buf_ptr[i]++] = '\0'; + got_command = 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] = realloc (sim_rem_buf[i], sim_rem_buf_size[i]); + } + sim_rem_buf[i][sim_rem_buf_ptr[i]++] = c; + sim_rem_buf[i][sim_rem_buf_ptr[i]] = '\0'; + break; + } + } + tmxr_send_buffered_data (lp); /* try to flush any buffered data */ + printf ("Remote Console Command from %s> %s\n", lp->ipad, sim_rem_buf[i]); + if (sim_log) + fprintf (sim_log, "Remote Console Command from %s> %s\n", lp->ipad, sim_rem_buf[i]); + if (strlen(sim_rem_buf[i]) >= sizeof(cbuf)) { + tmxr_linemsg (lp, "Line too long. Ignored. Continuing Simulator execution\r\n"); + tmxr_send_buffered_data (lp); /* try to flush any buffered data */ + break; + } + strcpy (cbuf, sim_rem_buf[i]); + if (cbuf[0] == '\0') + continue; + sim_rem_buf_ptr[i] = 0; + sim_rem_buf[i][sim_rem_buf_ptr[i]] = '\0'; + sim_sub_args (cbuf, sizeof(cbuf), argv); + cptr = cbuf; + cptr = get_glyph (cptr, gbuf, 0); /* get command glyph */ + sim_switches = 0; /* init switches */ + cmd_log_start = ftell (sim_log); + if (!find_cmd (gbuf)) /* validate command */ + stat = SCPE_UNK; + else { + if ((cmdp = find_ctab (allowed_remote_cmds, gbuf))) {/* lookup command */ + if (cmdp->action != &x_continue_cmd) + stat = cmdp->action (cmdp->arg, cptr); /* if found, exec */ + else + stat = SCPE_OK; + } + else + stat = SCPE_INVREM; + } + stat_nomessage = stat & SCPE_NOMESSAGE; /* extract possible message supression flag */ + stat = SCPE_BARE_STATUS(stat); /* remove possible flag */ + if (!stat_nomessage) { /* displaying message status? */ + if (cmdp && (cmdp->message)) /* special message handler? */ + cmdp->message (NULL, stat); /* let it deal with display */ + else + if (stat >= SCPE_BASE) { /* error? */ + printf ("%s\n", sim_error_text (stat)); + if (sim_log) + fprintf (sim_log, "%s\n", sim_error_text (stat)); + } + } + fflush (sim_log); + fseek (sim_log, cmd_log_start, SEEK_SET); + cbuf[sizeof(cbuf)-1] = '\0'; + while (fgets (cbuf, sizeof(cbuf)-1, sim_log)) { + tmxr_linemsg (lp, cbuf); + tmxr_linemsg (lp, "\r"); + tmxr_send_buffered_data (lp); + } + if (cmdp->action == &x_continue_cmd) + break; + } + } +sim_activate_after(uptr, 100000); /* check again in 100 milliaeconds */ +return SCPE_OK; +} + +t_stat sim_rem_con_reset (DEVICE *dptr) +{ +if (sim_rem_con_tmxr.lines) + return sim_rem_con_poll_svc (&dptr->units[0]); /* establish polling as needed */ +return SCPE_OK; +} + +static t_stat sim_set_rem_telnet (int32 flag, char *cptr) +{ +t_stat r; + +if (flag) { + r = sim_parse_addr (cptr, NULL, 0, NULL, NULL, 0, NULL, NULL); + if (r == SCPE_OK) { + if (!sim_log) { + printf ("Logging must be enabled to activate Remote Console support\n"); + return SCPE_ARG; + } + if (sim_rem_con_tmxr.master) /* already open? */ + sim_set_rem_telnet (0, NULL); /* close first */ + if (sim_rem_con_tmxr.lines == 0) /* Ir no connection limit set */ + sim_set_rem_connections (0, "1"); /* use 1 */ + sim_register_internal_device (&sim_remote_console); + r = tmxr_attach (&sim_rem_con_tmxr, &sim_rem_con_unit[0], cptr);/* open master socket */ + if (r == SCPE_OK) + sim_activate_after(&sim_rem_con_unit[0], 1000000); /* check for connection in 1 second */ + return r; + } + return SCPE_NOPARAM; + } +else { + if (sim_rem_con_tmxr.master) + tmxr_detach (&sim_rem_con_tmxr, &sim_rem_con_unit[0]); + } +return SCPE_OK; +} + +static t_stat sim_set_rem_connections (int32 flag, char *cptr) +{ +int32 lines = atoi(cptr); +int32 i; + +if (sim_rem_con_tmxr.master) + return SCPE_ARG; +for (i=0; iname, gbuf, sizeof((*pref)->name)-1); - *pf = sim_fopen (gbuf, (binary ? "ab" : "a")); /* open file */ + *pf = sim_fopen (gbuf, (binary ? "a+b" : "a+")); /* open file */ if (*pf == NULL) { /* error? */ free (*pref); *pref = NULL; @@ -1130,7 +1460,7 @@ typedef struct { SENSE_BUF cmd_mode = { 0 }; SENSE_BUF run_mode = { 0 }; -t_stat sim_os_ttinit (void) +static t_stat sim_os_ttinit (void) { unsigned int status; IOSB iosb; @@ -1149,7 +1479,7 @@ run_mode.stat2 = cmd_mode.stat2 | TT2$M_PASTHRU; return SCPE_OK; } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { unsigned int status; IOSB iosb; @@ -1161,7 +1491,7 @@ if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { unsigned int status; IOSB iosb; @@ -1173,19 +1503,19 @@ if ((status != SS$_NORMAL) || (iosb.status != SS$_NORMAL)) return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { sim_ttcmd (); sys$dassgn (tty_chan); return SCPE_OK; } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { return isatty (fileno (stdin)); } -t_stat sim_os_poll_kbd_data (void) +static t_stat sim_os_poll_kbd_data (void) { unsigned int status, term[2]; unsigned char buf[4]; @@ -1210,7 +1540,7 @@ if (sim_brk_char && (buf[0] == sim_brk_char)) return (buf[0] | SCPE_KFLAG); } -t_stat sim_os_poll_kbd (void) +static t_stat sim_os_poll_kbd (void) { t_stat response; @@ -1221,7 +1551,7 @@ if (response = buffered_character) { return sim_os_poll_kbd_data (); } -t_bool sim_os_poll_kbd_ready (int ms_timeout) +static t_bool sim_os_poll_kbd_ready (int ms_timeout) { unsigned int status, term[2]; unsigned char buf[4]; @@ -1244,7 +1574,7 @@ return TRUE; } -t_stat sim_os_putchar (int32 out) +static t_stat sim_os_putchar (int32 out) { unsigned int status; char c; @@ -1300,7 +1630,7 @@ ControlHandler(DWORD dwCtrlType) return FALSE; } -t_stat sim_os_ttinit (void) +static t_stat sim_os_ttinit (void) { SetConsoleCtrlHandler( ControlHandler, TRUE ); std_input = GetStdHandle (STD_INPUT_HANDLE); @@ -1311,7 +1641,7 @@ if ((std_input) && /* Not Background proces return SCPE_OK; } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { if ((std_input) && /* If Not Background process? */ (std_input != INVALID_HANDLE_VALUE) && @@ -1326,7 +1656,7 @@ SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_BELOW_NORMAL); return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { if (sim_log) { fflush (sim_log); @@ -1340,19 +1670,19 @@ if ((std_input) && /* If Not Background pro return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { return SCPE_OK; } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { DWORD Mode; return (std_input) && (std_input != INVALID_HANDLE_VALUE) && GetConsoleMode (std_input, &Mode); } -t_stat sim_os_poll_kbd (void) +static t_stat sim_os_poll_kbd (void) { int c = -1; DWORD nkbevents, nkbevent; @@ -1395,7 +1725,7 @@ if ((sim_brk_char && ((c & 0177) == sim_brk_char)) || (c & SCPE_BREAK)) return c | SCPE_KFLAG; } -t_bool sim_os_poll_kbd_ready (int ms_timeout) +static t_bool sim_os_poll_kbd_ready (int ms_timeout) { sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_poll_kbd_ready()\n"); if ((std_input == NULL) || /* No keyboard for */ @@ -1406,7 +1736,7 @@ if ((std_input == NULL) || /* No keyboard for */ return (WAIT_OBJECT_0 == WaitForSingleObject (std_input, ms_timeout)); } -t_stat sim_os_putchar (int32 c) +static t_stat sim_os_putchar (int32 c) { DWORD unused; @@ -1421,32 +1751,32 @@ return SCPE_OK; #include -t_stat sim_os_ttinit (void) +static t_stat sim_os_ttinit (void) { return SCPE_OK; } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { return SCPE_OK; } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { return 1; } -t_stat sim_os_poll_kbd (void) +static t_stat sim_os_poll_kbd (void) { int c; @@ -1477,13 +1807,13 @@ if (sim_brk_char && ((c & 0177) == sim_brk_char)) return c | SCPE_KFLAG; } -t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */ +static t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */ { sim_os_ms_sleep (MIN(20,ms_timeout)); /* Wait a little */ return TRUE; /* force a poll */ } -t_stat sim_os_putchar (int32 c) +static t_stat sim_os_putchar (int32 c) { if (c != 0177) { #if defined (__EMX__) @@ -1609,7 +1939,7 @@ int ps_getch(void) { /* Note that this only works if the call to sim_ttinit comes before any output to the console */ -t_stat sim_os_ttinit (void) { +static t_stat sim_os_ttinit (void) { int i; /* this blank will later be replaced by the number of characters */ char title[50] = " "; @@ -1632,27 +1962,27 @@ t_stat sim_os_ttinit (void) { return SCPE_OK; } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { return SCPE_OK; } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { return 1; } -t_stat sim_os_poll_kbd (void) +static t_stat sim_os_poll_kbd (void) { int c; @@ -1667,13 +1997,13 @@ if (sim_brk_char && ((c & 0177) == sim_brk_char)) return c | SCPE_KFLAG; } -t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */ +static t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */ { sim_os_ms_sleep (MIN(20,ms_timeout)); /* Wait a little */ return TRUE; /* force a poll */ } -t_stat sim_os_putchar (int32 c) +static t_stat sim_os_putchar (int32 c) { if (c != 0177) { putchar (c); @@ -1695,7 +2025,7 @@ struct tchars cmdtchars,runtchars; /* V7 editing */ struct ltchars cmdltchars,runltchars; /* 4.2 BSD editing */ int cmdfl,runfl; /* TTY flags */ -t_stat sim_os_ttinit (void) +static t_stat sim_os_ttinit (void) { cmdfl = fcntl (0, F_GETFL, 0); /* get old flags and status */ runfl = cmdfl | FNDELAY; @@ -1722,7 +2052,7 @@ runltchars.t_lnextc = 0xFF; return SCPE_OK; /* return success */ } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { runtchars.t_intrc = sim_int_char; /* in case changed */ fcntl (0, F_SETFL, runfl); /* non-block mode */ @@ -1736,7 +2066,7 @@ nice (10); /* lower priority */ return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { nice (-10); /* restore priority */ fcntl (0, F_SETFL, cmdfl); /* block mode */ @@ -1749,17 +2079,17 @@ if (ioctl (0, TIOCSLTC, &cmdltchars) < 0) return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { return sim_ttcmd (); } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { return isatty (0); } -t_stat sim_os_poll_kbd (void) +static static t_stat sim_os_poll_kbd (void) { int status; unsigned char buf[1]; @@ -1771,7 +2101,7 @@ if (sim_brk_char && (buf[0] == sim_brk_char)) else return (buf[0] | SCPE_KFLAG); } -t_bool sim_os_poll_kbd_ready (int ms_timeout) +static t_bool sim_os_poll_kbd_ready (int ms_timeout) { fd_set readfds; struct timeval timeout; @@ -1787,7 +2117,7 @@ timeout.tv_usec = (ms_timeout*1000)%1000000; return (1 == select (1, &readfds, NULL, NULL, &timeout)); } -t_stat sim_os_putchar (int32 out) +static t_stat sim_os_putchar (int32 out) { char c; @@ -1806,7 +2136,7 @@ return SCPE_OK; struct termios cmdtty, runtty; static int prior_norm = 1; -t_stat sim_os_ttinit (void) +static t_stat sim_os_ttinit (void) { if (!isatty (fileno (stdin))) /* skip if !tty */ return SCPE_OK; @@ -1848,7 +2178,7 @@ runtty.c_cc[VSTATUS] = 0; return SCPE_OK; } -t_stat sim_os_ttrun (void) +static t_stat sim_os_ttrun (void) { if (!isatty (fileno (stdin))) /* skip if !tty */ return SCPE_OK; @@ -1863,7 +2193,7 @@ if (prior_norm) { /* at normal pri? */ return SCPE_OK; } -t_stat sim_os_ttcmd (void) +static t_stat sim_os_ttcmd (void) { if (!isatty (fileno (stdin))) /* skip if !tty */ return SCPE_OK; @@ -1877,17 +2207,17 @@ if (tcsetattr (0, TCSAFLUSH, &cmdtty) < 0) return SCPE_OK; } -t_stat sim_os_ttclose (void) +static t_stat sim_os_ttclose (void) { return sim_ttcmd (); } -t_bool sim_os_ttisatty (void) +static t_bool sim_os_ttisatty (void) { return isatty (fileno (stdin)); } -t_stat sim_os_poll_kbd (void) +static t_stat sim_os_poll_kbd (void) { int status; unsigned char buf[1]; @@ -1899,7 +2229,7 @@ if (sim_brk_char && (buf[0] == sim_brk_char)) else return (buf[0] | SCPE_KFLAG); } -t_bool sim_os_poll_kbd_ready (int ms_timeout) +static t_bool sim_os_poll_kbd_ready (int ms_timeout) { fd_set readfds; struct timeval timeout; @@ -1915,7 +2245,7 @@ timeout.tv_usec = (ms_timeout*1000)%1000000; return (1 == select (1, &readfds, NULL, NULL, &timeout)); } -t_stat sim_os_putchar (int32 out) +static t_stat sim_os_putchar (int32 out) { char c; diff --git a/sim_console.h b/sim_console.h index c3cb332c..50a76c6d 100644 --- a/sim_console.h +++ b/sim_console.h @@ -52,6 +52,7 @@ #define TT_GET_MODE(x) (((x) >> TTUF_V_MODE) & TTUF_M_MODE) t_stat sim_set_console (int32 flag, char *cptr); +t_stat sim_set_remote_console (int32 flag, char *cptr); t_stat sim_set_kmap (int32 flag, char *cptr); t_stat sim_set_telnet (int32 flag, char *cptr); t_stat sim_set_notelnet (int32 flag, char *cptr); @@ -68,6 +69,7 @@ t_stat sim_set_cons_nolog (int32 flg, char *cptr); t_stat sim_set_deboff (int32 flag, char *cptr); t_stat sim_set_pchar (int32 flag, char *cptr); t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); +t_stat sim_show_remote_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat sim_show_telnet (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); t_stat sim_show_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr); diff --git a/sim_defs.h b/sim_defs.h index 30782661..fa20011e 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -273,8 +273,9 @@ typedef uint32 t_addr; #define SCPE_TTMO (SCPE_BASE + 40) /* Telnet conn timeout */ #define SCPE_STALL (SCPE_BASE + 41) /* Telnet conn stall */ #define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */ +#define SCPE_INVREM (SCPE_BASE + 43) /* invalid remote console command */ -#define SCPE_MAX_ERR (SCPE_BASE + 43) /* Maximum SCPE Error Value */ +#define SCPE_MAX_ERR (SCPE_BASE + 44) /* Maximum SCPE Error Value */ #define SCPE_KFLAG 0x1000 /* tti data flag */ #define SCPE_BREAK 0x2000 /* tti break flag */ #define SCPE_NOMESSAGE 0x10000000 /* message display supression flag */