version 1.89, 2015/10/20 21:12:09 |
version 1.90, 2015/10/27 13:23:24 |
|
|
*/ |
*/ |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <sys/queue.h> |
|
#include <sys/uio.h> |
|
|
|
#include <imsg.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <time.h> |
#include <time.h> |
|
|
} |
} |
|
|
void |
void |
server_write_ready(struct client *c) |
|
{ |
|
if (c->flags & CLIENT_CONTROL) |
|
return; |
|
server_write_client(c, MSG_READY, NULL, 0); |
|
} |
|
|
|
int |
|
server_write_client(struct client *c, enum msgtype type, const void *buf, |
|
size_t len) |
|
{ |
|
struct imsgbuf *ibuf = &c->ibuf; |
|
int error; |
|
|
|
if (c->flags & CLIENT_BAD) |
|
return (-1); |
|
log_debug("writing %d to client %p", type, c); |
|
error = imsg_compose(ibuf, type, PROTOCOL_VERSION, -1, -1, |
|
(void *) buf, len); |
|
if (error == 1) |
|
server_update_event(c); |
|
return (error == 1 ? 0 : -1); |
|
} |
|
|
|
void |
|
server_write_session(struct session *s, enum msgtype type, const void *buf, |
|
size_t len) |
|
{ |
|
struct client *c; |
|
|
|
TAILQ_FOREACH(c, &clients, entry) { |
|
if (c->session == s) |
|
server_write_client(c, type, buf, len); |
|
} |
|
} |
|
|
|
void |
|
server_redraw_client(struct client *c) |
server_redraw_client(struct client *c) |
{ |
{ |
c->flags |= CLIENT_REDRAW; |
c->flags |= CLIENT_REDRAW; |
|
|
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_E3)); |
tty_raw(&c->tty, tty_term_string(c->tty.term, TTYC_E3)); |
|
|
c->flags |= CLIENT_SUSPENDED; |
c->flags |= CLIENT_SUSPENDED; |
server_write_client(c, MSG_LOCK, cmd, strlen(cmd) + 1); |
proc_send_s(c->peer, MSG_LOCK, cmd); |
} |
} |
|
|
void |
void |
|
|
server_clear_identify(c); |
server_clear_identify(c); |
} |
} |
|
|
void |
|
server_update_event(struct client *c) |
|
{ |
|
short events; |
|
|
|
events = 0; |
|
if (!(c->flags & CLIENT_BAD)) |
|
events |= EV_READ; |
|
if (c->ibuf.w.queued > 0) |
|
events |= EV_WRITE; |
|
if (event_initialized(&c->event)) |
|
event_del(&c->event); |
|
event_set(&c->event, c->ibuf.fd, events, server_client_callback, c); |
|
event_add(&c->event, NULL); |
|
} |
|
|
|
/* Push stdout to client if possible. */ |
/* Push stdout to client if possible. */ |
void |
void |
server_push_stdout(struct client *c) |
server_push_stdout(struct client *c) |
|
|
memcpy(data.data, EVBUFFER_DATA(c->stdout_data), size); |
memcpy(data.data, EVBUFFER_DATA(c->stdout_data), size); |
data.size = size; |
data.size = size; |
|
|
if (server_write_client(c, MSG_STDOUT, &data, sizeof data) == 0) |
if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) == 0) |
evbuffer_drain(c->stdout_data, size); |
evbuffer_drain(c->stdout_data, size); |
} |
} |
|
|
|
|
memcpy(data.data, EVBUFFER_DATA(c->stderr_data), size); |
memcpy(data.data, EVBUFFER_DATA(c->stderr_data), size); |
data.size = size; |
data.size = size; |
|
|
if (server_write_client(c, MSG_STDERR, &data, sizeof data) == 0) |
if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) == 0) |
evbuffer_drain(c->stderr_data, size); |
evbuffer_drain(c->stderr_data, size); |
} |
} |
|
|
|
|
if (c->stdin_closed) |
if (c->stdin_closed) |
c->stdin_callback(c, 1, c->stdin_callback_data); |
c->stdin_callback(c, 1, c->stdin_callback_data); |
|
|
server_write_client(c, MSG_STDIN, NULL, 0); |
proc_send(c->peer, MSG_STDIN, -1, NULL, 0); |
|
|
return (0); |
return (0); |
} |
} |