version 1.108, 2013/10/10 12:13:56 |
version 1.109, 2013/10/10 12:26:36 |
|
|
|
|
int server_client_msg_dispatch(struct client *); |
int server_client_msg_dispatch(struct client *); |
void server_client_msg_command(struct client *, struct imsg *); |
void server_client_msg_command(struct client *, struct imsg *); |
void server_client_msg_identify( |
void server_client_msg_identify(struct client *, struct imsg *); |
struct client *, struct msg_identify_data *, int); |
|
void server_client_msg_shell(struct client *); |
void server_client_msg_shell(struct client *); |
|
|
/* Create a new client. */ |
/* Create a new client. */ |
|
|
*/ |
*/ |
if (c->flags & CLIENT_TERMINAL) |
if (c->flags & CLIENT_TERMINAL) |
tty_free(&c->tty); |
tty_free(&c->tty); |
|
free(c->ttyname); |
|
free(c->term); |
|
|
evbuffer_free (c->stdin_data); |
evbuffer_free (c->stdin_data); |
evbuffer_free (c->stdout_data); |
evbuffer_free (c->stdout_data); |
|
|
screen_free(&c->status); |
screen_free(&c->status); |
|
|
free(c->title); |
free(c->title); |
|
close(c->cwd); |
|
|
evtimer_del(&c->repeat_timer); |
evtimer_del(&c->repeat_timer); |
|
|
|
|
|
|
free(c->prompt_string); |
free(c->prompt_string); |
free(c->prompt_buffer); |
free(c->prompt_buffer); |
free(c->cwd); |
|
|
|
c->cmdq->dead = 1; |
c->cmdq->dead = 1; |
cmdq_free(c->cmdq); |
cmdq_free(c->cmdq); |
|
|
server_client_msg_dispatch(struct client *c) |
server_client_msg_dispatch(struct client *c) |
{ |
{ |
struct imsg imsg; |
struct imsg imsg; |
struct msg_identify_data identifydata; |
|
struct msg_environ_data environdata; |
|
struct msg_stdin_data stdindata; |
struct msg_stdin_data stdindata; |
const char *data; |
const char *data; |
ssize_t n, datalen; |
ssize_t n, datalen; |
|
|
|
|
log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd); |
log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd); |
switch (imsg.hdr.type) { |
switch (imsg.hdr.type) { |
case MSG_IDENTIFY: |
case MSG_IDENTIFY_FLAGS: |
if (datalen != sizeof identifydata) |
case MSG_IDENTIFY_TERM: |
fatalx("bad MSG_IDENTIFY size"); |
case MSG_IDENTIFY_TTYNAME: |
memcpy(&identifydata, imsg.data, sizeof identifydata); |
case MSG_IDENTIFY_CWD: |
|
case MSG_IDENTIFY_STDIN: |
server_client_msg_identify(c, &identifydata, imsg.fd); |
case MSG_IDENTIFY_ENVIRON: |
|
case MSG_IDENTIFY_DONE: |
|
server_client_msg_identify(c, &imsg); |
break; |
break; |
case MSG_COMMAND: |
case MSG_COMMAND: |
server_client_msg_command(c, &imsg); |
server_client_msg_command(c, &imsg); |
|
|
server_redraw_client(c); |
server_redraw_client(c); |
recalculate_sizes(); |
recalculate_sizes(); |
break; |
break; |
case MSG_ENVIRON: |
|
if (datalen != sizeof environdata) |
|
fatalx("bad MSG_ENVIRON size"); |
|
memcpy(&environdata, imsg.data, sizeof environdata); |
|
|
|
environdata.var[(sizeof environdata.var) - 1] = '\0'; |
|
if (strchr(environdata.var, '=') != NULL) |
|
environ_put(&c->environ, environdata.var); |
|
break; |
|
case MSG_SHELL: |
case MSG_SHELL: |
if (datalen != 0) |
if (datalen != 0) |
fatalx("bad MSG_SHELL size"); |
fatalx("bad MSG_SHELL size"); |
|
|
server_client_msg_shell(c); |
server_client_msg_shell(c); |
break; |
break; |
default: |
|
fatalx("unexpected message"); |
|
} |
} |
|
|
imsg_free(&imsg); |
imsg_free(&imsg); |
|
|
|
|
/* Handle identify message. */ |
/* Handle identify message. */ |
void |
void |
server_client_msg_identify( |
server_client_msg_identify(struct client *c, struct imsg *imsg) |
struct client *c, struct msg_identify_data *data, int fd) |
|
{ |
{ |
c->cwd = NULL; |
const char *data; |
data->cwd[(sizeof data->cwd) - 1] = '\0'; |
size_t datalen; |
if (*data->cwd != '\0') |
int flags; |
c->cwd = xstrdup(data->cwd); |
|
|
|
if (data->flags & CLIENT_CONTROL) { |
if (c->flags & CLIENT_IDENTIFIED) |
|
fatalx("out-of-order identify message"); |
|
|
|
data = imsg->data; |
|
datalen = imsg->hdr.len - IMSG_HEADER_SIZE; |
|
|
|
switch (imsg->hdr.type) { |
|
case MSG_IDENTIFY_FLAGS: |
|
if (datalen != sizeof flags) |
|
fatalx("bad MSG_IDENTIFY_FLAGS size"); |
|
memcpy(&flags, data, sizeof flags); |
|
c->flags |= flags; |
|
break; |
|
case MSG_IDENTIFY_TERM: |
|
if (data[datalen - 1] != '\0') |
|
fatalx("bad MSG_IDENTIFY_TERM string"); |
|
c->term = xstrdup(data); |
|
break; |
|
case MSG_IDENTIFY_TTYNAME: |
|
if (data[datalen - 1] != '\0') |
|
fatalx("bad MSG_IDENTIFY_TTYNAME string"); |
|
c->ttyname = xstrdup(data); |
|
break; |
|
case MSG_IDENTIFY_CWD: |
|
if (datalen != 0) |
|
fatalx("bad MSG_IDENTIFY_CWD size"); |
|
c->cwd = imsg->fd; |
|
break; |
|
case MSG_IDENTIFY_STDIN: |
|
if (datalen != 0) |
|
fatalx("bad MSG_IDENTIFY_STDIN size"); |
|
c->fd = imsg->fd; |
|
break; |
|
case MSG_IDENTIFY_ENVIRON: |
|
if (data[datalen - 1] != '\0') |
|
fatalx("bad MSG_IDENTIFY_ENVIRON string"); |
|
if (strchr(data, '=') != NULL) |
|
environ_put(&c->environ, data); |
|
break; |
|
default: |
|
break; |
|
} |
|
|
|
if (imsg->hdr.type != MSG_IDENTIFY_DONE) |
|
return; |
|
c->flags |= CLIENT_IDENTIFIED; |
|
|
|
#ifdef __CYGWIN__ |
|
c->fd = open(c->ttyname, O_RDWR|O_NOCTTY); |
|
c->cwd = open(".", O_RDONLY); |
|
#endif |
|
|
|
if (c->flags & CLIENT_CONTROL) { |
c->stdin_callback = control_callback; |
c->stdin_callback = control_callback; |
|
|
evbuffer_free(c->stderr_data); |
evbuffer_free(c->stderr_data); |
c->stderr_data = c->stdout_data; |
c->stderr_data = c->stdout_data; |
c->flags |= CLIENT_CONTROL; |
|
if (data->flags & CLIENT_CONTROLCONTROL) |
if (c->flags & CLIENT_CONTROLCONTROL) |
evbuffer_add_printf(c->stdout_data, "\033P1000p"); |
evbuffer_add_printf(c->stdout_data, "\033P1000p"); |
server_write_client(c, MSG_STDIN, NULL, 0); |
server_write_client(c, MSG_STDIN, NULL, 0); |
|
|
c->tty.fd = -1; |
c->tty.fd = -1; |
c->tty.log_fd = -1; |
c->tty.log_fd = -1; |
|
|
close(fd); |
close(c->fd); |
|
c->fd = -1; |
|
|
return; |
return; |
} |
} |
|
|
if (fd == -1) |
if (c->fd == -1) |
return; |
return; |
if (!isatty(fd)) { |
if (!isatty(c->fd)) { |
close(fd); |
close(c->fd); |
|
c->fd = -1; |
return; |
return; |
} |
} |
data->term[(sizeof data->term) - 1] = '\0'; |
tty_init(&c->tty, c, c->fd, c->term); |
tty_init(&c->tty, c, fd, data->term); |
if (c->flags & CLIENT_UTF8) |
if (data->flags & CLIENT_UTF8) |
|
c->tty.flags |= TTY_UTF8; |
c->tty.flags |= TTY_UTF8; |
if (data->flags & CLIENT_256COLOURS) |
if (c->flags & CLIENT_256COLOURS) |
c->tty.term_flags |= TERM_256COLOURS; |
c->tty.term_flags |= TERM_256COLOURS; |
|
|
tty_resize(&c->tty); |
tty_resize(&c->tty); |
|
|
if (!(data->flags & CLIENT_CONTROL)) |
if (!(c->flags & CLIENT_CONTROL)) |
c->flags |= CLIENT_TERMINAL; |
c->flags |= CLIENT_TERMINAL; |
} |
} |
|
|