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