use when they have data from the network. Replaces the utterly daft
inbuf / inbuf_head / term_out() interface, which only made sense
when feeding to terminal.c. (terminal.c now implements
from_backend() as a small function that gateways to the old
interface.)
As a side effect, from_backend() also has an `is_stderr' parameter,
so scp can once again separate the server's pronouncements on stderr
from the actual protocol progress on stdout.
git-svn-id: svn://svn.tartarus.org/sgt/putty@729
cda61777-01e9-0310-a592-
d414129be87e
*/
static void c_write (char *buf, int len) {
- while (len--)
- c_write1(*buf++);
+ from_backend(0, buf, len);
+}
+
+static void c_write1 (char c) {
+ c_write(&c, 1);
}
static char *term_buf = NULL;
}
}
-HANDLE outhandle;
+HANDLE outhandle, errhandle;
DWORD orig_console_mode;
void begin_session(void) {
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), orig_console_mode);
}
-void term_out(void)
-{
- int reap;
+void from_backend(int is_stderr, char *data, int len) {
+ int pos;
DWORD ret;
- reap = 0;
- while (reap < inbuf_head) {
- if (!WriteFile(outhandle, inbuf+reap, inbuf_head-reap, &ret, NULL))
+ HANDLE h = (is_stderr ? errhandle : outhandle);
+
+ pos = 0;
+ while (pos < len) {
+ if (!WriteFile(h, data+pos, len-pos, &ret, NULL))
return; /* give up in panic */
- reap += ret;
+ pos += ret;
}
- inbuf_head = 0;
}
struct input_data {
GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &orig_console_mode);
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
outhandle = GetStdHandle(STD_OUTPUT_HANDLE);
+ errhandle = GetStdHandle(STD_ERROR_HANDLE);
/*
* Now we must send the back end oodles of stuff.
break;
}
}
- term_out();
} else if (n == 1) {
if (idata.len > 0) {
back->send(idata.buffer, idata.len);
GLOBAL int font_width, font_height;
-#define c_write1(_C) do { if (inbuf_head >= INBUF_SIZE) term_out(); \
- inbuf[inbuf_head++] = (_C) ; } while(0)
#define INBUF_SIZE 2048
GLOBAL unsigned char inbuf[INBUF_SIZE];
GLOBAL int inbuf_head;
void term_blink(int set_cursor);
void term_paste(void);
void term_nopaste(void);
+void from_backend(int is_stderr, char *data, int len);
/*
* Exports from raw.c.
}
static void c_write (char *buf, int len) {
- while (len--)
- c_write1(*buf++);
+ from_backend(0, buf, len);
}
/*
* is available.
*
* To do this, we repeatedly call the SSH protocol module, with our
- * own trap in term_out() to catch the data that comes back. We do
- * this until we have enough data.
+ * own trap in from_backend() to catch the data that comes back. We
+ * do this until we have enough data.
*/
static unsigned char *outptr; /* where to put the data */
static unsigned outlen; /* how much data required */
static unsigned char *pending = NULL; /* any spare data */
static unsigned pendlen=0, pendsize=0; /* length and phys. size of buffer */
-void term_out(void) {
+void from_backend(int is_stderr, char *data, int datalen) {
+ unsigned char *p = (unsigned char *)data;
+ unsigned len = (unsigned)datalen;
+
/*
- * Here we must deal with a block of data, in `inbuf', size
- * `inbuf_head'.
+ * stderr data is just spouted to local stderr and otherwise
+ * ignored.
*/
- unsigned char *p = inbuf;
- unsigned len = inbuf_head;
+ if (is_stderr) {
+ fwrite(data, 1, len, stderr);
+ return;
+ }
inbuf_head = 0;
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return 0; /* doom */
back->msg(0, FD_READ);
- term_out();
}
return len;
if (select(1, &readfds, NULL, NULL, NULL) < 0)
return; /* doom */
back->msg(0, FD_READ);
- term_out();
}
}
fputc(buf[i], stderr);
return;
}
- while (len--)
- c_write1(*buf++);
-}
-
-static void c_writedata (char *buf, int len) {
- while (len--)
- c_write1(*buf++);
+ from_backend(1, buf, len);
}
/*
if (pktin.type == SSH1_SMSG_STDOUT_DATA ||
pktin.type == SSH1_SMSG_STDERR_DATA) {
long len = GET_32BIT(pktin.body);
- c_writedata(pktin.body+4, len);
+ from_backend(pktin.type == SSH1_SMSG_STDERR_DATA,
+ pktin.body+4, len);
} else if (pktin.type == SSH1_MSG_DISCONNECT) {
ssh_state = SSH_STATE_CLOSED;
logevent("Received disconnect request");
continue; /* extended but not stderr */
ssh2_pkt_getstring(&data, &length);
if (data) {
- c_writedata(data, length);
+ from_backend(pktin.type == SSH2_MSG_CHANNEL_EXTENDED_DATA,
+ data, length);
/*
* Enlarge the window again at the remote side,
* just in case it ever runs down and they fail
try_write();
}
+static void c_write1(int c) {
+ char cc = (char)c;
+ from_backend(0, &cc, 1);
+}
+
static void log_option (char *sender, int cmd, int option) {
char buf[50];
sprintf(buf, "%s:\t%s %s", sender,
deselect();
term_update();
}
+
+/*
+ * from_backend(), to get data from the backend for the terminal.
+ */
+void from_backend(int is_stderr, char *data, int len) {
+ while (len--) {
+ if (inbuf_head >= INBUF_SIZE)
+ term_out();
+ inbuf[inbuf_head++] = *data++;
+ }
+}
static int recurse = 0;
int nc = -1;
- if(0)
- {
- char buf[256];
- char * p;
- sprintf(buf, "cc(%d,%d)", first, second);
- for(p=buf; *p; p++)
- c_write1(*p);
- }
-
for(c=composetbl; *c; c++) {
if( (*c)[0] == first && (*c)[1] == second)
{
if ((nc=check_compose(compose_char,ch)) == -1)
{
- c_write1('\007');
+ MessageBeep(MB_ICONHAND);
return 0;
}
*p++ = xlat_kbd2tty((unsigned char)nc);