1 /* $OpenBSD: server-client.c,v 1.205 2016/12/07 09:16:13 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/ioctl.h> 21 #include <sys/uio.h> 22 23 #include <errno.h> 24 #include <event.h> 25 #include <fcntl.h> 26 #include <imsg.h> 27 #include <paths.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <time.h> 31 #include <unistd.h> 32 33 #include "tmux.h" 34 35 static void server_client_free(int, short, void *); 36 static void server_client_check_focus(struct window_pane *); 37 static void server_client_check_resize(struct window_pane *); 38 static key_code server_client_check_mouse(struct client *); 39 static void server_client_repeat_timer(int, short, void *); 40 static void server_client_click_timer(int, short, void *); 41 static void server_client_check_exit(struct client *); 42 static void server_client_check_redraw(struct client *); 43 static void server_client_set_title(struct client *); 44 static void server_client_reset_state(struct client *); 45 static int server_client_assume_paste(struct session *); 46 47 static void server_client_dispatch(struct imsg *, void *); 48 static void server_client_dispatch_command(struct client *, struct imsg *); 49 static void server_client_dispatch_identify(struct client *, struct imsg *); 50 static void server_client_dispatch_shell(struct client *); 51 52 /* Check if this client is inside this server. */ 53 int 54 server_client_check_nested(struct client *c) 55 { 56 struct environ_entry *envent; 57 struct window_pane *wp; 58 59 if (c->tty.path == NULL) 60 return (0); 61 62 envent = environ_find(c->environ, "TMUX"); 63 if (envent == NULL || *envent->value == '\0') 64 return (0); 65 66 RB_FOREACH(wp, window_pane_tree, &all_window_panes) { 67 if (strcmp(wp->tty, c->tty.path) == 0) 68 return (1); 69 } 70 return (0); 71 } 72 73 /* Set client key table. */ 74 void 75 server_client_set_key_table(struct client *c, const char *name) 76 { 77 if (name == NULL) 78 name = server_client_get_key_table(c); 79 80 key_bindings_unref_table(c->keytable); 81 c->keytable = key_bindings_get_table(name, 1); 82 c->keytable->references++; 83 } 84 85 /* Get default key table. */ 86 const char * 87 server_client_get_key_table(struct client *c) 88 { 89 struct session *s = c->session; 90 const char *name; 91 92 if (s == NULL) 93 return ("root"); 94 95 name = options_get_string(s->options, "key-table"); 96 if (*name == '\0') 97 return ("root"); 98 return (name); 99 } 100 101 /* Is this client using the default key table? */ 102 int 103 server_client_is_default_key_table(struct client *c) 104 { 105 return (strcmp(c->keytable->name, server_client_get_key_table(c)) == 0); 106 } 107 108 /* Create a new client. */ 109 void 110 server_client_create(int fd) 111 { 112 struct client *c; 113 114 setblocking(fd, 0); 115 116 c = xcalloc(1, sizeof *c); 117 c->references = 1; 118 c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c); 119 120 if (gettimeofday(&c->creation_time, NULL) != 0) 121 fatal("gettimeofday failed"); 122 memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); 123 124 c->environ = environ_create(); 125 126 c->fd = -1; 127 c->cwd = NULL; 128 129 TAILQ_INIT(&c->queue); 130 131 c->stdin_data = evbuffer_new(); 132 c->stdout_data = evbuffer_new(); 133 c->stderr_data = evbuffer_new(); 134 135 c->tty.fd = -1; 136 c->title = NULL; 137 138 c->session = NULL; 139 c->last_session = NULL; 140 c->tty.sx = 80; 141 c->tty.sy = 24; 142 143 screen_init(&c->status, c->tty.sx, 1, 0); 144 145 c->message_string = NULL; 146 TAILQ_INIT(&c->message_log); 147 148 c->prompt_string = NULL; 149 c->prompt_buffer = NULL; 150 c->prompt_index = 0; 151 152 c->flags |= CLIENT_FOCUSED; 153 154 c->keytable = key_bindings_get_table("root", 1); 155 c->keytable->references++; 156 157 evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); 158 evtimer_set(&c->click_timer, server_client_click_timer, c); 159 160 TAILQ_INSERT_TAIL(&clients, c, entry); 161 log_debug("new client %p", c); 162 } 163 164 /* Open client terminal if needed. */ 165 int 166 server_client_open(struct client *c, char **cause) 167 { 168 if (c->flags & CLIENT_CONTROL) 169 return (0); 170 171 if (strcmp(c->ttyname, "/dev/tty") == 0) { 172 *cause = xstrdup("can't use /dev/tty"); 173 return (-1); 174 } 175 176 if (!(c->flags & CLIENT_TERMINAL)) { 177 *cause = xstrdup("not a terminal"); 178 return (-1); 179 } 180 181 if (tty_open(&c->tty, cause) != 0) 182 return (-1); 183 184 return (0); 185 } 186 187 /* Lost a client. */ 188 void 189 server_client_lost(struct client *c) 190 { 191 struct message_entry *msg, *msg1; 192 193 c->flags |= CLIENT_DEAD; 194 195 server_clear_identify(c, NULL); 196 status_prompt_clear(c); 197 status_message_clear(c); 198 199 if (c->stdin_callback != NULL) 200 c->stdin_callback(c, 1, c->stdin_callback_data); 201 202 TAILQ_REMOVE(&clients, c, entry); 203 log_debug("lost client %p", c); 204 205 /* 206 * If CLIENT_TERMINAL hasn't been set, then tty_init hasn't been called 207 * and tty_free might close an unrelated fd. 208 */ 209 if (c->flags & CLIENT_TERMINAL) 210 tty_free(&c->tty); 211 free(c->ttyname); 212 free(c->term); 213 214 evbuffer_free(c->stdin_data); 215 evbuffer_free(c->stdout_data); 216 if (c->stderr_data != c->stdout_data) 217 evbuffer_free(c->stderr_data); 218 219 if (event_initialized(&c->status_timer)) 220 evtimer_del(&c->status_timer); 221 screen_free(&c->status); 222 223 free(c->title); 224 free((void *)c->cwd); 225 226 evtimer_del(&c->repeat_timer); 227 evtimer_del(&c->click_timer); 228 229 key_bindings_unref_table(c->keytable); 230 231 if (event_initialized(&c->identify_timer)) 232 evtimer_del(&c->identify_timer); 233 234 free(c->message_string); 235 if (event_initialized(&c->message_timer)) 236 evtimer_del(&c->message_timer); 237 TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) { 238 free(msg->msg); 239 TAILQ_REMOVE(&c->message_log, msg, entry); 240 free(msg); 241 } 242 243 free(c->prompt_string); 244 free(c->prompt_buffer); 245 246 environ_free(c->environ); 247 248 proc_remove_peer(c->peer); 249 c->peer = NULL; 250 251 server_client_unref(c); 252 253 server_add_accept(0); /* may be more file descriptors now */ 254 255 recalculate_sizes(); 256 server_check_unattached(); 257 server_update_socket(); 258 } 259 260 /* Remove reference from a client. */ 261 void 262 server_client_unref(struct client *c) 263 { 264 log_debug("unref client %p (%d references)", c, c->references); 265 266 c->references--; 267 if (c->references == 0) 268 event_once(-1, EV_TIMEOUT, server_client_free, c, NULL); 269 } 270 271 /* Free dead client. */ 272 static void 273 server_client_free(__unused int fd, __unused short events, void *arg) 274 { 275 struct client *c = arg; 276 277 log_debug("free client %p (%d references)", c, c->references); 278 279 if (!TAILQ_EMPTY(&c->queue)) 280 fatalx("queue not empty"); 281 282 if (c->references == 0) 283 free(c); 284 } 285 286 /* Detach a client. */ 287 void 288 server_client_detach(struct client *c, enum msgtype msgtype) 289 { 290 struct session *s = c->session; 291 292 if (s == NULL) 293 return; 294 295 notify_client("client-detached", c); 296 proc_send_s(c->peer, msgtype, s->name); 297 } 298 299 /* Check for mouse keys. */ 300 static key_code 301 server_client_check_mouse(struct client *c) 302 { 303 struct session *s = c->session; 304 struct mouse_event *m = &c->tty.mouse; 305 struct window *w; 306 struct window_pane *wp; 307 u_int x, y, b; 308 int flag; 309 key_code key; 310 struct timeval tv; 311 enum { NOTYPE, DOWN, UP, DRAG, WHEEL, DOUBLE, TRIPLE } type = NOTYPE; 312 enum { NOWHERE, PANE, STATUS, BORDER } where = NOWHERE; 313 314 log_debug("mouse %02x at %u,%u (last %u,%u) (%d)", m->b, m->x, m->y, 315 m->lx, m->ly, c->tty.mouse_drag_flag); 316 317 /* What type of event is this? */ 318 if (MOUSE_DRAG(m->b)) { 319 type = DRAG; 320 if (c->tty.mouse_drag_flag) { 321 x = m->x, y = m->y, b = m->b; 322 log_debug("drag update at %u,%u", x, y); 323 } else { 324 x = m->lx, y = m->ly, b = m->lb; 325 log_debug("drag start at %u,%u", x, y); 326 } 327 } else if (MOUSE_WHEEL(m->b)) { 328 type = WHEEL; 329 x = m->x, y = m->y, b = m->b; 330 log_debug("wheel at %u,%u", x, y); 331 } else if (MOUSE_RELEASE(m->b)) { 332 type = UP; 333 x = m->x, y = m->y, b = m->lb; 334 log_debug("up at %u,%u", x, y); 335 } else { 336 if (c->flags & CLIENT_DOUBLECLICK) { 337 evtimer_del(&c->click_timer); 338 c->flags &= ~CLIENT_DOUBLECLICK; 339 if (m->b == c->click_button) { 340 type = DOUBLE; 341 x = m->x, y = m->y, b = m->b; 342 log_debug("double-click at %u,%u", x, y); 343 flag = CLIENT_TRIPLECLICK; 344 goto add_timer; 345 } 346 } else if (c->flags & CLIENT_TRIPLECLICK) { 347 evtimer_del(&c->click_timer); 348 c->flags &= ~CLIENT_TRIPLECLICK; 349 if (m->b == c->click_button) { 350 type = TRIPLE; 351 x = m->x, y = m->y, b = m->b; 352 log_debug("triple-click at %u,%u", x, y); 353 goto have_event; 354 } 355 } 356 357 type = DOWN; 358 x = m->x, y = m->y, b = m->b; 359 log_debug("down at %u,%u", x, y); 360 flag = CLIENT_DOUBLECLICK; 361 362 add_timer: 363 if (KEYC_CLICK_TIMEOUT != 0) { 364 c->flags |= flag; 365 c->click_button = m->b; 366 367 tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000; 368 tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L; 369 evtimer_del(&c->click_timer); 370 evtimer_add(&c->click_timer, &tv); 371 } 372 } 373 374 have_event: 375 if (type == NOTYPE) 376 return (KEYC_UNKNOWN); 377 378 /* Always save the session. */ 379 m->s = s->id; 380 381 /* Is this on the status line? */ 382 m->statusat = status_at_line(c); 383 if (m->statusat != -1 && y == (u_int)m->statusat) { 384 w = status_get_window_at(c, x); 385 if (w == NULL) 386 return (KEYC_UNKNOWN); 387 m->w = w->id; 388 where = STATUS; 389 } else 390 m->w = -1; 391 392 /* Not on status line. Adjust position and check for border or pane. */ 393 if (where == NOWHERE) { 394 if (m->statusat == 0 && y > 0) 395 y--; 396 else if (m->statusat > 0 && y >= (u_int)m->statusat) 397 y = m->statusat - 1; 398 399 TAILQ_FOREACH(wp, &s->curw->window->panes, entry) { 400 if ((wp->xoff + wp->sx == x && 401 wp->yoff <= 1 + y && 402 wp->yoff + wp->sy >= y) || 403 (wp->yoff + wp->sy == y && 404 wp->xoff <= 1 + x && 405 wp->xoff + wp->sx >= x)) 406 break; 407 } 408 if (wp != NULL) 409 where = BORDER; 410 else { 411 wp = window_get_active_at(s->curw->window, x, y); 412 if (wp != NULL) { 413 where = PANE; 414 log_debug("mouse at %u,%u is on pane %%%u", 415 x, y, wp->id); 416 } 417 } 418 if (where == NOWHERE) 419 return (KEYC_UNKNOWN); 420 m->wp = wp->id; 421 m->w = wp->window->id; 422 } else 423 m->wp = -1; 424 425 /* Stop dragging if needed. */ 426 if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag) { 427 if (c->tty.mouse_drag_release != NULL) 428 c->tty.mouse_drag_release(c, m); 429 430 c->tty.mouse_drag_update = NULL; 431 c->tty.mouse_drag_release = NULL; 432 433 /* 434 * End a mouse drag by passing a MouseDragEnd key corresponding 435 * to the button that started the drag. 436 */ 437 switch (c->tty.mouse_drag_flag) { 438 case 1: 439 if (where == PANE) 440 key = KEYC_MOUSEDRAGEND1_PANE; 441 if (where == STATUS) 442 key = KEYC_MOUSEDRAGEND1_STATUS; 443 if (where == BORDER) 444 key = KEYC_MOUSEDRAGEND1_BORDER; 445 break; 446 case 2: 447 if (where == PANE) 448 key = KEYC_MOUSEDRAGEND2_PANE; 449 if (where == STATUS) 450 key = KEYC_MOUSEDRAGEND2_STATUS; 451 if (where == BORDER) 452 key = KEYC_MOUSEDRAGEND2_BORDER; 453 break; 454 case 3: 455 if (where == PANE) 456 key = KEYC_MOUSEDRAGEND3_PANE; 457 if (where == STATUS) 458 key = KEYC_MOUSEDRAGEND3_STATUS; 459 if (where == BORDER) 460 key = KEYC_MOUSEDRAGEND3_BORDER; 461 break; 462 default: 463 key = KEYC_MOUSE; 464 break; 465 } 466 c->tty.mouse_drag_flag = 0; 467 468 return (key); 469 } 470 471 /* Convert to a key binding. */ 472 key = KEYC_UNKNOWN; 473 switch (type) { 474 case NOTYPE: 475 break; 476 case DRAG: 477 if (c->tty.mouse_drag_update != NULL) 478 key = KEYC_DRAGGING; 479 else { 480 switch (MOUSE_BUTTONS(b)) { 481 case 0: 482 if (where == PANE) 483 key = KEYC_MOUSEDRAG1_PANE; 484 if (where == STATUS) 485 key = KEYC_MOUSEDRAG1_STATUS; 486 if (where == BORDER) 487 key = KEYC_MOUSEDRAG1_BORDER; 488 break; 489 case 1: 490 if (where == PANE) 491 key = KEYC_MOUSEDRAG2_PANE; 492 if (where == STATUS) 493 key = KEYC_MOUSEDRAG2_STATUS; 494 if (where == BORDER) 495 key = KEYC_MOUSEDRAG2_BORDER; 496 break; 497 case 2: 498 if (where == PANE) 499 key = KEYC_MOUSEDRAG3_PANE; 500 if (where == STATUS) 501 key = KEYC_MOUSEDRAG3_STATUS; 502 if (where == BORDER) 503 key = KEYC_MOUSEDRAG3_BORDER; 504 break; 505 } 506 } 507 508 /* 509 * Begin a drag by setting the flag to a non-zero value that 510 * corresponds to the mouse button in use. 511 */ 512 c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; 513 break; 514 case WHEEL: 515 if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) { 516 if (where == PANE) 517 key = KEYC_WHEELUP_PANE; 518 if (where == STATUS) 519 key = KEYC_WHEELUP_STATUS; 520 if (where == BORDER) 521 key = KEYC_WHEELUP_BORDER; 522 } else { 523 if (where == PANE) 524 key = KEYC_WHEELDOWN_PANE; 525 if (where == STATUS) 526 key = KEYC_WHEELDOWN_STATUS; 527 if (where == BORDER) 528 key = KEYC_WHEELDOWN_BORDER; 529 } 530 break; 531 case UP: 532 switch (MOUSE_BUTTONS(b)) { 533 case 0: 534 if (where == PANE) 535 key = KEYC_MOUSEUP1_PANE; 536 if (where == STATUS) 537 key = KEYC_MOUSEUP1_STATUS; 538 if (where == BORDER) 539 key = KEYC_MOUSEUP1_BORDER; 540 break; 541 case 1: 542 if (where == PANE) 543 key = KEYC_MOUSEUP2_PANE; 544 if (where == STATUS) 545 key = KEYC_MOUSEUP2_STATUS; 546 if (where == BORDER) 547 key = KEYC_MOUSEUP2_BORDER; 548 break; 549 case 2: 550 if (where == PANE) 551 key = KEYC_MOUSEUP3_PANE; 552 if (where == STATUS) 553 key = KEYC_MOUSEUP3_STATUS; 554 if (where == BORDER) 555 key = KEYC_MOUSEUP3_BORDER; 556 break; 557 } 558 break; 559 case DOWN: 560 switch (MOUSE_BUTTONS(b)) { 561 case 0: 562 if (where == PANE) 563 key = KEYC_MOUSEDOWN1_PANE; 564 if (where == STATUS) 565 key = KEYC_MOUSEDOWN1_STATUS; 566 if (where == BORDER) 567 key = KEYC_MOUSEDOWN1_BORDER; 568 break; 569 case 1: 570 if (where == PANE) 571 key = KEYC_MOUSEDOWN2_PANE; 572 if (where == STATUS) 573 key = KEYC_MOUSEDOWN2_STATUS; 574 if (where == BORDER) 575 key = KEYC_MOUSEDOWN2_BORDER; 576 break; 577 case 2: 578 if (where == PANE) 579 key = KEYC_MOUSEDOWN3_PANE; 580 if (where == STATUS) 581 key = KEYC_MOUSEDOWN3_STATUS; 582 if (where == BORDER) 583 key = KEYC_MOUSEDOWN3_BORDER; 584 break; 585 } 586 break; 587 case DOUBLE: 588 switch (MOUSE_BUTTONS(b)) { 589 case 0: 590 if (where == PANE) 591 key = KEYC_DOUBLECLICK1_PANE; 592 if (where == STATUS) 593 key = KEYC_DOUBLECLICK1_STATUS; 594 if (where == BORDER) 595 key = KEYC_DOUBLECLICK1_BORDER; 596 break; 597 case 1: 598 if (where == PANE) 599 key = KEYC_DOUBLECLICK2_PANE; 600 if (where == STATUS) 601 key = KEYC_DOUBLECLICK2_STATUS; 602 if (where == BORDER) 603 key = KEYC_DOUBLECLICK2_BORDER; 604 break; 605 case 2: 606 if (where == PANE) 607 key = KEYC_DOUBLECLICK3_PANE; 608 if (where == STATUS) 609 key = KEYC_DOUBLECLICK3_STATUS; 610 if (where == BORDER) 611 key = KEYC_DOUBLECLICK3_BORDER; 612 break; 613 } 614 break; 615 case TRIPLE: 616 switch (MOUSE_BUTTONS(b)) { 617 case 0: 618 if (where == PANE) 619 key = KEYC_TRIPLECLICK1_PANE; 620 if (where == STATUS) 621 key = KEYC_TRIPLECLICK1_STATUS; 622 if (where == BORDER) 623 key = KEYC_TRIPLECLICK1_BORDER; 624 break; 625 case 1: 626 if (where == PANE) 627 key = KEYC_TRIPLECLICK2_PANE; 628 if (where == STATUS) 629 key = KEYC_TRIPLECLICK2_STATUS; 630 if (where == BORDER) 631 key = KEYC_TRIPLECLICK2_BORDER; 632 break; 633 case 2: 634 if (where == PANE) 635 key = KEYC_TRIPLECLICK3_PANE; 636 if (where == STATUS) 637 key = KEYC_TRIPLECLICK3_STATUS; 638 if (where == BORDER) 639 key = KEYC_TRIPLECLICK3_BORDER; 640 break; 641 } 642 break; 643 } 644 if (key == KEYC_UNKNOWN) 645 return (KEYC_UNKNOWN); 646 647 /* Apply modifiers if any. */ 648 if (b & MOUSE_MASK_META) 649 key |= KEYC_ESCAPE; 650 if (b & MOUSE_MASK_CTRL) 651 key |= KEYC_CTRL; 652 if (b & MOUSE_MASK_SHIFT) 653 key |= KEYC_SHIFT; 654 655 return (key); 656 } 657 658 /* Is this fast enough to probably be a paste? */ 659 static int 660 server_client_assume_paste(struct session *s) 661 { 662 struct timeval tv; 663 int t; 664 665 if ((t = options_get_number(s->options, "assume-paste-time")) == 0) 666 return (0); 667 668 timersub(&s->activity_time, &s->last_activity_time, &tv); 669 if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) { 670 log_debug("session %s pasting (flag %d)", s->name, 671 !!(s->flags & SESSION_PASTING)); 672 if (s->flags & SESSION_PASTING) 673 return (1); 674 s->flags |= SESSION_PASTING; 675 return (0); 676 } 677 log_debug("session %s not pasting", s->name); 678 s->flags &= ~SESSION_PASTING; 679 return (0); 680 } 681 682 /* Handle data key input from client. */ 683 void 684 server_client_handle_key(struct client *c, key_code key) 685 { 686 struct mouse_event *m = &c->tty.mouse; 687 struct session *s = c->session; 688 struct window *w; 689 struct window_pane *wp; 690 struct timeval tv; 691 const char *name; 692 struct key_table *table; 693 struct key_binding bd_find, *bd; 694 int xtimeout; 695 struct cmd_find_state fs; 696 697 /* Check the client is good to accept input. */ 698 if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) 699 return; 700 w = s->curw->window; 701 702 /* Update the activity timer. */ 703 if (gettimeofday(&c->activity_time, NULL) != 0) 704 fatal("gettimeofday failed"); 705 session_update_activity(s, &c->activity_time); 706 707 /* Number keys jump to pane in identify mode. */ 708 if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') { 709 if (c->flags & CLIENT_READONLY) 710 return; 711 window_unzoom(w); 712 wp = window_pane_at_index(w, key - '0'); 713 if (wp != NULL && !window_pane_visible(wp)) 714 wp = NULL; 715 server_clear_identify(c, wp); 716 return; 717 } 718 719 /* Handle status line. */ 720 if (!(c->flags & CLIENT_READONLY)) { 721 status_message_clear(c); 722 server_clear_identify(c, NULL); 723 } 724 if (c->prompt_string != NULL) { 725 if (c->flags & CLIENT_READONLY) 726 return; 727 if (status_prompt_key(c, key) == 0) 728 return; 729 } 730 731 /* Check for mouse keys. */ 732 m->valid = 0; 733 if (key == KEYC_MOUSE) { 734 if (c->flags & CLIENT_READONLY) 735 return; 736 key = server_client_check_mouse(c); 737 if (key == KEYC_UNKNOWN) 738 return; 739 740 m->valid = 1; 741 m->key = key; 742 743 /* 744 * Mouse drag is in progress, so fire the callback (now that 745 * the mouse event is valid). 746 */ 747 if (key == KEYC_DRAGGING) { 748 c->tty.mouse_drag_update(c, m); 749 return; 750 } 751 } else 752 m->valid = 0; 753 754 /* Find affected pane. */ 755 if (KEYC_IS_MOUSE(key) && m->valid) 756 wp = cmd_mouse_pane(m, NULL, NULL); 757 else 758 wp = w->active; 759 760 /* Forward mouse keys if disabled. */ 761 if (key == KEYC_MOUSE && !options_get_number(s->options, "mouse")) 762 goto forward; 763 764 /* Treat everything as a regular key when pasting is detected. */ 765 if (!KEYC_IS_MOUSE(key) && server_client_assume_paste(s)) 766 goto forward; 767 768 retry: 769 /* 770 * Work out the current key table. If the pane is in a mode, use 771 * the mode table instead of the default key table. 772 */ 773 name = NULL; 774 if (wp != NULL && wp->mode != NULL && wp->mode->key_table != NULL) 775 name = wp->mode->key_table(wp); 776 if (name == NULL || !server_client_is_default_key_table(c)) 777 table = c->keytable; 778 else 779 table = key_bindings_get_table(name, 1); 780 if (wp == NULL) 781 log_debug("key table %s (no pane)", table->name); 782 else 783 log_debug("key table %s (pane %%%u)", table->name, wp->id); 784 785 /* 786 * The prefix always takes precedence and forces a switch to the prefix 787 * table, unless we are already there. 788 */ 789 if ((key == (key_code)options_get_number(s->options, "prefix") || 790 key == (key_code)options_get_number(s->options, "prefix2")) && 791 strcmp(table->name, "prefix") != 0) { 792 server_client_set_key_table(c, "prefix"); 793 server_status_client(c); 794 return; 795 } 796 797 /* Try to see if there is a key binding in the current table. */ 798 bd_find.key = key; 799 bd = RB_FIND(key_bindings, &table->key_bindings, &bd_find); 800 if (bd != NULL) { 801 /* 802 * Key was matched in this table. If currently repeating but a 803 * non-repeating binding was found, stop repeating and try 804 * again in the root table. 805 */ 806 if ((c->flags & CLIENT_REPEAT) && !bd->can_repeat) { 807 server_client_set_key_table(c, NULL); 808 c->flags &= ~CLIENT_REPEAT; 809 server_status_client(c); 810 goto retry; 811 } 812 813 /* 814 * Take a reference to this table to make sure the key binding 815 * doesn't disappear. 816 */ 817 table->references++; 818 819 /* 820 * If this is a repeating key, start the timer. Otherwise reset 821 * the client back to the root table. 822 */ 823 xtimeout = options_get_number(s->options, "repeat-time"); 824 if (xtimeout != 0 && bd->can_repeat) { 825 c->flags |= CLIENT_REPEAT; 826 827 tv.tv_sec = xtimeout / 1000; 828 tv.tv_usec = (xtimeout % 1000) * 1000L; 829 evtimer_del(&c->repeat_timer); 830 evtimer_add(&c->repeat_timer, &tv); 831 } else { 832 c->flags &= ~CLIENT_REPEAT; 833 server_client_set_key_table(c, NULL); 834 } 835 server_status_client(c); 836 837 /* Find default state if the pane is known. */ 838 cmd_find_clear_state(&fs, NULL, 0); 839 if (wp != NULL) { 840 fs.s = s; 841 fs.wl = fs.s->curw; 842 fs.w = fs.wl->window; 843 fs.wp = wp; 844 cmd_find_log_state(__func__, &fs); 845 846 if (!cmd_find_valid_state(&fs)) 847 fatalx("invalid key state"); 848 } 849 850 /* Dispatch the key binding. */ 851 key_bindings_dispatch(bd, c, m, &fs); 852 key_bindings_unref_table(table); 853 return; 854 } 855 856 /* 857 * No match in this table. If repeating, switch the client back to the 858 * root table and try again. 859 */ 860 if (c->flags & CLIENT_REPEAT) { 861 server_client_set_key_table(c, NULL); 862 c->flags &= ~CLIENT_REPEAT; 863 server_status_client(c); 864 goto retry; 865 } 866 867 /* If no match and we're not in the root table, that's it. */ 868 if (name == NULL && !server_client_is_default_key_table(c)) { 869 log_debug("no key in key table %s", table->name); 870 server_client_set_key_table(c, NULL); 871 server_status_client(c); 872 return; 873 } 874 875 forward: 876 if (c->flags & CLIENT_READONLY) 877 return; 878 if (wp != NULL) 879 window_pane_key(wp, c, s, key, m); 880 } 881 882 /* Client functions that need to happen every loop. */ 883 void 884 server_client_loop(void) 885 { 886 struct client *c; 887 struct window *w; 888 struct window_pane *wp; 889 int focus; 890 891 TAILQ_FOREACH(c, &clients, entry) { 892 server_client_check_exit(c); 893 if (c->session != NULL) { 894 server_client_check_redraw(c); 895 server_client_reset_state(c); 896 } 897 } 898 899 /* 900 * Any windows will have been redrawn as part of clients, so clear 901 * their flags now. Also check pane focus and resize. 902 */ 903 focus = options_get_number(global_options, "focus-events"); 904 RB_FOREACH(w, windows, &windows) { 905 w->flags &= ~WINDOW_REDRAW; 906 TAILQ_FOREACH(wp, &w->panes, entry) { 907 if (wp->fd != -1) { 908 if (focus) 909 server_client_check_focus(wp); 910 server_client_check_resize(wp); 911 } 912 wp->flags &= ~PANE_REDRAW; 913 } 914 check_window_name(w); 915 } 916 } 917 918 static void 919 server_client_resize_event(__unused int fd, __unused short events, void *data) 920 { 921 struct window_pane *wp = data; 922 struct winsize ws; 923 924 evtimer_del(&wp->resize_timer); 925 926 if (!(wp->flags & PANE_RESIZE)) 927 return; 928 929 memset(&ws, 0, sizeof ws); 930 ws.ws_col = wp->sx; 931 ws.ws_row = wp->sy; 932 933 if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) 934 fatal("ioctl failed"); 935 936 wp->flags &= ~PANE_RESIZE; 937 } 938 939 /* Check if pane should be resized. */ 940 static void 941 server_client_check_resize(struct window_pane *wp) 942 { 943 struct timeval tv = { .tv_usec = 250000 }; 944 945 if (!(wp->flags & PANE_RESIZE)) 946 return; 947 948 if (!event_initialized(&wp->resize_timer)) 949 evtimer_set(&wp->resize_timer, server_client_resize_event, wp); 950 951 /* 952 * The first resize should happen immediately, so if the timer is not 953 * running, do it now. 954 */ 955 if (!evtimer_pending(&wp->resize_timer, NULL)) 956 server_client_resize_event(-1, 0, wp); 957 958 /* 959 * If the pane is in the alternate screen, let the timer expire and 960 * resize to give the application a chance to redraw. If not, keep 961 * pushing the timer back. 962 */ 963 if (wp->saved_grid != NULL && evtimer_pending(&wp->resize_timer, NULL)) 964 return; 965 evtimer_del(&wp->resize_timer); 966 evtimer_add(&wp->resize_timer, &tv); 967 } 968 969 /* Check whether pane should be focused. */ 970 static void 971 server_client_check_focus(struct window_pane *wp) 972 { 973 struct client *c; 974 int push; 975 976 /* Do we need to push the focus state? */ 977 push = wp->flags & PANE_FOCUSPUSH; 978 wp->flags &= ~PANE_FOCUSPUSH; 979 980 /* If we don't care about focus, forget it. */ 981 if (!(wp->base.mode & MODE_FOCUSON)) 982 return; 983 984 /* If we're not the active pane in our window, we're not focused. */ 985 if (wp->window->active != wp) 986 goto not_focused; 987 988 /* If we're in a mode, we're not focused. */ 989 if (wp->screen != &wp->base) 990 goto not_focused; 991 992 /* 993 * If our window is the current window in any focused clients with an 994 * attached session, we're focused. 995 */ 996 TAILQ_FOREACH(c, &clients, entry) { 997 if (c->session == NULL || !(c->flags & CLIENT_FOCUSED)) 998 continue; 999 if (c->session->flags & SESSION_UNATTACHED) 1000 continue; 1001 1002 if (c->session->curw->window == wp->window) 1003 goto focused; 1004 } 1005 1006 not_focused: 1007 if (push || (wp->flags & PANE_FOCUSED)) 1008 bufferevent_write(wp->event, "\033[O", 3); 1009 wp->flags &= ~PANE_FOCUSED; 1010 return; 1011 1012 focused: 1013 if (push || !(wp->flags & PANE_FOCUSED)) 1014 bufferevent_write(wp->event, "\033[I", 3); 1015 wp->flags |= PANE_FOCUSED; 1016 } 1017 1018 /* 1019 * Update cursor position and mode settings. The scroll region and attributes 1020 * are cleared when idle (waiting for an event) as this is the most likely time 1021 * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a 1022 * compromise between excessive resets and likelihood of an interrupt. 1023 * 1024 * tty_region/tty_reset/tty_update_mode already take care of not resetting 1025 * things that are already in their default state. 1026 */ 1027 static void 1028 server_client_reset_state(struct client *c) 1029 { 1030 struct window *w = c->session->curw->window; 1031 struct window_pane *wp = w->active; 1032 struct screen *s = wp->screen; 1033 struct options *oo = c->session->options; 1034 int status, mode, o; 1035 1036 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1037 return; 1038 1039 tty_region_off(&c->tty); 1040 tty_margin_off(&c->tty); 1041 1042 status = options_get_number(oo, "status"); 1043 if (!window_pane_visible(wp) || wp->yoff + s->cy >= c->tty.sy - status) 1044 tty_cursor(&c->tty, 0, 0); 1045 else { 1046 o = status && options_get_number(oo, "status-position") == 0; 1047 tty_cursor(&c->tty, wp->xoff + s->cx, o + wp->yoff + s->cy); 1048 } 1049 1050 /* 1051 * Set mouse mode if requested. To support dragging, always use button 1052 * mode. 1053 */ 1054 mode = s->mode; 1055 if (options_get_number(oo, "mouse")) 1056 mode = (mode & ~ALL_MOUSE_MODES) | MODE_MOUSE_BUTTON; 1057 1058 /* Set the terminal mode and reset attributes. */ 1059 tty_update_mode(&c->tty, mode, s); 1060 tty_reset(&c->tty); 1061 } 1062 1063 /* Repeat time callback. */ 1064 static void 1065 server_client_repeat_timer(__unused int fd, __unused short events, void *data) 1066 { 1067 struct client *c = data; 1068 1069 if (c->flags & CLIENT_REPEAT) { 1070 server_client_set_key_table(c, NULL); 1071 c->flags &= ~CLIENT_REPEAT; 1072 server_status_client(c); 1073 } 1074 } 1075 1076 /* Double-click callback. */ 1077 static void 1078 server_client_click_timer(__unused int fd, __unused short events, void *data) 1079 { 1080 struct client *c = data; 1081 1082 c->flags &= ~(CLIENT_DOUBLECLICK|CLIENT_TRIPLECLICK); 1083 } 1084 1085 /* Check if client should be exited. */ 1086 static void 1087 server_client_check_exit(struct client *c) 1088 { 1089 if (!(c->flags & CLIENT_EXIT)) 1090 return; 1091 1092 if (EVBUFFER_LENGTH(c->stdin_data) != 0) 1093 return; 1094 if (EVBUFFER_LENGTH(c->stdout_data) != 0) 1095 return; 1096 if (EVBUFFER_LENGTH(c->stderr_data) != 0) 1097 return; 1098 1099 proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval); 1100 c->flags &= ~CLIENT_EXIT; 1101 } 1102 1103 /* Check for client redraws. */ 1104 static void 1105 server_client_check_redraw(struct client *c) 1106 { 1107 struct session *s = c->session; 1108 struct tty *tty = &c->tty; 1109 struct window_pane *wp; 1110 int flags, masked; 1111 1112 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1113 return; 1114 1115 if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) { 1116 if (options_get_number(s->options, "set-titles")) 1117 server_client_set_title(c); 1118 screen_redraw_update(c); /* will adjust flags */ 1119 } 1120 1121 flags = tty->flags & (TTY_FREEZE|TTY_NOCURSOR); 1122 tty->flags = (tty->flags & ~TTY_FREEZE) | TTY_NOCURSOR; 1123 1124 if (c->flags & CLIENT_REDRAW) { 1125 tty_update_mode(tty, tty->mode, NULL); 1126 screen_redraw_screen(c, 1, 1, 1); 1127 c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS); 1128 } else if (c->flags & CLIENT_REDRAWWINDOW) { 1129 tty_update_mode(tty, tty->mode, NULL); 1130 TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) 1131 screen_redraw_pane(c, wp); 1132 c->flags &= ~CLIENT_REDRAWWINDOW; 1133 } else { 1134 TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) { 1135 if (wp->flags & PANE_REDRAW) { 1136 tty_update_mode(tty, tty->mode, NULL); 1137 screen_redraw_pane(c, wp); 1138 } 1139 } 1140 } 1141 1142 masked = c->flags & (CLIENT_BORDERS|CLIENT_STATUS); 1143 if (masked != 0) 1144 tty_update_mode(tty, tty->mode, NULL); 1145 if (masked == CLIENT_BORDERS) 1146 screen_redraw_screen(c, 0, 0, 1); 1147 else if (masked == CLIENT_STATUS) 1148 screen_redraw_screen(c, 0, 1, 0); 1149 else if (masked != 0) 1150 screen_redraw_screen(c, 0, 1, 1); 1151 1152 tty->flags = (tty->flags & ~(TTY_FREEZE|TTY_NOCURSOR)) | flags; 1153 tty_update_mode(tty, tty->mode, NULL); 1154 1155 c->flags &= ~(CLIENT_REDRAW|CLIENT_BORDERS|CLIENT_STATUS| 1156 CLIENT_STATUSFORCE); 1157 } 1158 1159 /* Set client title. */ 1160 static void 1161 server_client_set_title(struct client *c) 1162 { 1163 struct session *s = c->session; 1164 const char *template; 1165 char *title; 1166 struct format_tree *ft; 1167 1168 template = options_get_string(s->options, "set-titles-string"); 1169 1170 ft = format_create(NULL, 0); 1171 format_defaults(ft, c, NULL, NULL, NULL); 1172 1173 title = format_expand_time(ft, template, time(NULL)); 1174 if (c->title == NULL || strcmp(title, c->title) != 0) { 1175 free(c->title); 1176 c->title = xstrdup(title); 1177 tty_set_title(&c->tty, c->title); 1178 } 1179 free(title); 1180 1181 format_free(ft); 1182 } 1183 1184 /* Dispatch message from client. */ 1185 static void 1186 server_client_dispatch(struct imsg *imsg, void *arg) 1187 { 1188 struct client *c = arg; 1189 struct msg_stdin_data stdindata; 1190 const char *data; 1191 ssize_t datalen; 1192 struct session *s; 1193 1194 if (c->flags & CLIENT_DEAD) 1195 return; 1196 1197 if (imsg == NULL) { 1198 server_client_lost(c); 1199 return; 1200 } 1201 1202 data = imsg->data; 1203 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 1204 1205 switch (imsg->hdr.type) { 1206 case MSG_IDENTIFY_FLAGS: 1207 case MSG_IDENTIFY_TERM: 1208 case MSG_IDENTIFY_TTYNAME: 1209 case MSG_IDENTIFY_CWD: 1210 case MSG_IDENTIFY_STDIN: 1211 case MSG_IDENTIFY_ENVIRON: 1212 case MSG_IDENTIFY_CLIENTPID: 1213 case MSG_IDENTIFY_DONE: 1214 server_client_dispatch_identify(c, imsg); 1215 break; 1216 case MSG_COMMAND: 1217 server_client_dispatch_command(c, imsg); 1218 break; 1219 case MSG_STDIN: 1220 if (datalen != sizeof stdindata) 1221 fatalx("bad MSG_STDIN size"); 1222 memcpy(&stdindata, data, sizeof stdindata); 1223 1224 if (c->stdin_callback == NULL) 1225 break; 1226 if (stdindata.size <= 0) 1227 c->stdin_closed = 1; 1228 else { 1229 evbuffer_add(c->stdin_data, stdindata.data, 1230 stdindata.size); 1231 } 1232 c->stdin_callback(c, c->stdin_closed, 1233 c->stdin_callback_data); 1234 break; 1235 case MSG_RESIZE: 1236 if (datalen != 0) 1237 fatalx("bad MSG_RESIZE size"); 1238 1239 if (c->flags & CLIENT_CONTROL) 1240 break; 1241 if (tty_resize(&c->tty)) { 1242 recalculate_sizes(); 1243 server_redraw_client(c); 1244 } 1245 if (c->session != NULL) 1246 notify_client("client-resized", c); 1247 break; 1248 case MSG_EXITING: 1249 if (datalen != 0) 1250 fatalx("bad MSG_EXITING size"); 1251 1252 c->session = NULL; 1253 tty_close(&c->tty); 1254 proc_send(c->peer, MSG_EXITED, -1, NULL, 0); 1255 break; 1256 case MSG_WAKEUP: 1257 case MSG_UNLOCK: 1258 if (datalen != 0) 1259 fatalx("bad MSG_WAKEUP size"); 1260 1261 if (!(c->flags & CLIENT_SUSPENDED)) 1262 break; 1263 c->flags &= ~CLIENT_SUSPENDED; 1264 1265 if (c->tty.fd == -1) /* exited in the meantime */ 1266 break; 1267 s = c->session; 1268 1269 if (gettimeofday(&c->activity_time, NULL) != 0) 1270 fatal("gettimeofday failed"); 1271 1272 tty_start_tty(&c->tty); 1273 server_redraw_client(c); 1274 recalculate_sizes(); 1275 1276 if (s != NULL) 1277 session_update_activity(s, &c->activity_time); 1278 break; 1279 case MSG_SHELL: 1280 if (datalen != 0) 1281 fatalx("bad MSG_SHELL size"); 1282 1283 server_client_dispatch_shell(c); 1284 break; 1285 } 1286 } 1287 1288 /* Callback when command is done. */ 1289 static enum cmd_retval 1290 server_client_command_done(struct cmdq_item *item, __unused void *data) 1291 { 1292 struct client *c = item->client; 1293 1294 if (~c->flags & CLIENT_ATTACHED) 1295 c->flags |= CLIENT_EXIT; 1296 return (CMD_RETURN_NORMAL); 1297 } 1298 1299 /* Show an error message. */ 1300 static enum cmd_retval 1301 server_client_command_error(struct cmdq_item *item, void *data) 1302 { 1303 char *error = data; 1304 1305 cmdq_error(item, "%s", error); 1306 free(error); 1307 1308 return (CMD_RETURN_NORMAL); 1309 } 1310 1311 /* Handle command message. */ 1312 static void 1313 server_client_dispatch_command(struct client *c, struct imsg *imsg) 1314 { 1315 struct msg_command_data data; 1316 char *buf; 1317 size_t len; 1318 struct cmd_list *cmdlist = NULL; 1319 int argc; 1320 char **argv, *cause; 1321 1322 if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data) 1323 fatalx("bad MSG_COMMAND size"); 1324 memcpy(&data, imsg->data, sizeof data); 1325 1326 buf = (char *)imsg->data + sizeof data; 1327 len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data; 1328 if (len > 0 && buf[len - 1] != '\0') 1329 fatalx("bad MSG_COMMAND string"); 1330 1331 argc = data.argc; 1332 if (cmd_unpack_argv(buf, len, argc, &argv) != 0) { 1333 cause = xstrdup("command too long"); 1334 goto error; 1335 } 1336 1337 if (argc == 0) { 1338 argc = 1; 1339 argv = xcalloc(1, sizeof *argv); 1340 *argv = xstrdup("new-session"); 1341 } 1342 1343 if ((cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause)) == NULL) { 1344 cmd_free_argv(argc, argv); 1345 goto error; 1346 } 1347 cmd_free_argv(argc, argv); 1348 1349 cmdq_append(c, cmdq_get_command(cmdlist, NULL, NULL, 0)); 1350 cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); 1351 cmd_list_free(cmdlist); 1352 return; 1353 1354 error: 1355 cmdq_append(c, cmdq_get_callback(server_client_command_error, cause)); 1356 1357 if (cmdlist != NULL) 1358 cmd_list_free(cmdlist); 1359 1360 c->flags |= CLIENT_EXIT; 1361 } 1362 1363 /* Handle identify message. */ 1364 static void 1365 server_client_dispatch_identify(struct client *c, struct imsg *imsg) 1366 { 1367 const char *data, *home; 1368 size_t datalen; 1369 int flags; 1370 1371 if (c->flags & CLIENT_IDENTIFIED) 1372 fatalx("out-of-order identify message"); 1373 1374 data = imsg->data; 1375 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 1376 1377 switch (imsg->hdr.type) { 1378 case MSG_IDENTIFY_FLAGS: 1379 if (datalen != sizeof flags) 1380 fatalx("bad MSG_IDENTIFY_FLAGS size"); 1381 memcpy(&flags, data, sizeof flags); 1382 c->flags |= flags; 1383 log_debug("client %p IDENTIFY_FLAGS %#x", c, flags); 1384 break; 1385 case MSG_IDENTIFY_TERM: 1386 if (datalen == 0 || data[datalen - 1] != '\0') 1387 fatalx("bad MSG_IDENTIFY_TERM string"); 1388 c->term = xstrdup(data); 1389 log_debug("client %p IDENTIFY_TERM %s", c, data); 1390 break; 1391 case MSG_IDENTIFY_TTYNAME: 1392 if (datalen == 0 || data[datalen - 1] != '\0') 1393 fatalx("bad MSG_IDENTIFY_TTYNAME string"); 1394 c->ttyname = xstrdup(data); 1395 log_debug("client %p IDENTIFY_TTYNAME %s", c, data); 1396 break; 1397 case MSG_IDENTIFY_CWD: 1398 if (datalen == 0 || data[datalen - 1] != '\0') 1399 fatalx("bad MSG_IDENTIFY_CWD string"); 1400 if (access(data, X_OK) == 0) 1401 c->cwd = xstrdup(data); 1402 else if ((home = find_home()) != NULL) 1403 c->cwd = xstrdup(home); 1404 else 1405 c->cwd = xstrdup("/"); 1406 log_debug("client %p IDENTIFY_CWD %s", c, data); 1407 break; 1408 case MSG_IDENTIFY_STDIN: 1409 if (datalen != 0) 1410 fatalx("bad MSG_IDENTIFY_STDIN size"); 1411 c->fd = imsg->fd; 1412 log_debug("client %p IDENTIFY_STDIN %d", c, imsg->fd); 1413 break; 1414 case MSG_IDENTIFY_ENVIRON: 1415 if (datalen == 0 || data[datalen - 1] != '\0') 1416 fatalx("bad MSG_IDENTIFY_ENVIRON string"); 1417 if (strchr(data, '=') != NULL) 1418 environ_put(c->environ, data); 1419 log_debug("client %p IDENTIFY_ENVIRON %s", c, data); 1420 break; 1421 case MSG_IDENTIFY_CLIENTPID: 1422 if (datalen != sizeof c->pid) 1423 fatalx("bad MSG_IDENTIFY_CLIENTPID size"); 1424 memcpy(&c->pid, data, sizeof c->pid); 1425 log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid); 1426 break; 1427 default: 1428 break; 1429 } 1430 1431 if (imsg->hdr.type != MSG_IDENTIFY_DONE) 1432 return; 1433 c->flags |= CLIENT_IDENTIFIED; 1434 1435 if (c->flags & CLIENT_CONTROL) { 1436 c->stdin_callback = control_callback; 1437 1438 evbuffer_free(c->stderr_data); 1439 c->stderr_data = c->stdout_data; 1440 1441 if (c->flags & CLIENT_CONTROLCONTROL) 1442 evbuffer_add_printf(c->stdout_data, "\033P1000p"); 1443 proc_send(c->peer, MSG_STDIN, -1, NULL, 0); 1444 1445 c->tty.fd = -1; 1446 1447 close(c->fd); 1448 c->fd = -1; 1449 1450 return; 1451 } 1452 1453 if (c->fd == -1) 1454 return; 1455 if (tty_init(&c->tty, c, c->fd, c->term) != 0) { 1456 close(c->fd); 1457 c->fd = -1; 1458 return; 1459 } 1460 if (c->flags & CLIENT_UTF8) 1461 c->tty.flags |= TTY_UTF8; 1462 if (c->flags & CLIENT_256COLOURS) 1463 c->tty.term_flags |= TERM_256COLOURS; 1464 1465 tty_resize(&c->tty); 1466 1467 if (!(c->flags & CLIENT_CONTROL)) 1468 c->flags |= CLIENT_TERMINAL; 1469 } 1470 1471 /* Handle shell message. */ 1472 static void 1473 server_client_dispatch_shell(struct client *c) 1474 { 1475 const char *shell; 1476 1477 shell = options_get_string(global_s_options, "default-shell"); 1478 if (*shell == '\0' || areshell(shell)) 1479 shell = _PATH_BSHELL; 1480 proc_send_s(c->peer, MSG_SHELL, shell); 1481 1482 proc_kill_peer(c->peer); 1483 } 1484 1485 /* Event callback to push more stdout data if any left. */ 1486 static void 1487 server_client_stdout_cb(__unused int fd, __unused short events, void *arg) 1488 { 1489 struct client *c = arg; 1490 1491 if (~c->flags & CLIENT_DEAD) 1492 server_client_push_stdout(c); 1493 server_client_unref(c); 1494 } 1495 1496 /* Push stdout to client if possible. */ 1497 void 1498 server_client_push_stdout(struct client *c) 1499 { 1500 struct msg_stdout_data data; 1501 size_t sent, left; 1502 1503 left = EVBUFFER_LENGTH(c->stdout_data); 1504 while (left != 0) { 1505 sent = left; 1506 if (sent > sizeof data.data) 1507 sent = sizeof data.data; 1508 memcpy(data.data, EVBUFFER_DATA(c->stdout_data), sent); 1509 data.size = sent; 1510 1511 if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) != 0) 1512 break; 1513 evbuffer_drain(c->stdout_data, sent); 1514 1515 left = EVBUFFER_LENGTH(c->stdout_data); 1516 log_debug("%s: client %p, sent %zu, left %zu", __func__, c, 1517 sent, left); 1518 } 1519 if (left != 0) { 1520 c->references++; 1521 event_once(-1, EV_TIMEOUT, server_client_stdout_cb, c, NULL); 1522 log_debug("%s: client %p, queued", __func__, c); 1523 } 1524 } 1525 1526 /* Event callback to push more stderr data if any left. */ 1527 static void 1528 server_client_stderr_cb(__unused int fd, __unused short events, void *arg) 1529 { 1530 struct client *c = arg; 1531 1532 if (~c->flags & CLIENT_DEAD) 1533 server_client_push_stderr(c); 1534 server_client_unref(c); 1535 } 1536 1537 /* Push stderr to client if possible. */ 1538 void 1539 server_client_push_stderr(struct client *c) 1540 { 1541 struct msg_stderr_data data; 1542 size_t sent, left; 1543 1544 if (c->stderr_data == c->stdout_data) { 1545 server_client_push_stdout(c); 1546 return; 1547 } 1548 1549 left = EVBUFFER_LENGTH(c->stderr_data); 1550 while (left != 0) { 1551 sent = left; 1552 if (sent > sizeof data.data) 1553 sent = sizeof data.data; 1554 memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent); 1555 data.size = sent; 1556 1557 if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0) 1558 break; 1559 evbuffer_drain(c->stderr_data, sent); 1560 1561 left = EVBUFFER_LENGTH(c->stderr_data); 1562 log_debug("%s: client %p, sent %zu, left %zu", __func__, c, 1563 sent, left); 1564 } 1565 if (left != 0) { 1566 c->references++; 1567 event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL); 1568 log_debug("%s: client %p, queued", __func__, c); 1569 } 1570 } 1571