1 /* $OpenBSD$ */ 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 <stdlib.h> 27 #include <string.h> 28 #include <time.h> 29 #include <unistd.h> 30 31 #include "tmux.h" 32 33 static void server_client_free(int, short, void *); 34 static void server_client_check_focus(struct window_pane *); 35 static void server_client_check_resize(struct window_pane *); 36 static key_code server_client_check_mouse(struct client *, struct key_event *); 37 static void server_client_repeat_timer(int, short, void *); 38 static void server_client_click_timer(int, short, void *); 39 static void server_client_check_exit(struct client *); 40 static void server_client_check_redraw(struct client *); 41 static void server_client_set_title(struct client *); 42 static void server_client_reset_state(struct client *); 43 static int server_client_assume_paste(struct session *); 44 static void server_client_clear_overlay(struct client *); 45 46 static void server_client_dispatch(struct imsg *, void *); 47 static void server_client_dispatch_command(struct client *, struct imsg *); 48 static void server_client_dispatch_identify(struct client *, struct imsg *); 49 static void server_client_dispatch_shell(struct client *); 50 51 /* Number of attached clients. */ 52 u_int 53 server_client_how_many(void) 54 { 55 struct client *c; 56 u_int n; 57 58 n = 0; 59 TAILQ_FOREACH(c, &clients, entry) { 60 if (c->session != NULL && (~c->flags & CLIENT_DETACHING)) 61 n++; 62 } 63 return (n); 64 } 65 66 /* Overlay timer callback. */ 67 static void 68 server_client_overlay_timer(__unused int fd, __unused short events, void *data) 69 { 70 server_client_clear_overlay(data); 71 } 72 73 /* Set an overlay on client. */ 74 void 75 server_client_set_overlay(struct client *c, u_int delay, overlay_draw_cb drawcb, 76 overlay_key_cb keycb, overlay_free_cb freecb, void *data) 77 { 78 struct timeval tv; 79 80 if (c->overlay_draw != NULL) 81 server_client_clear_overlay(c); 82 83 tv.tv_sec = delay / 1000; 84 tv.tv_usec = (delay % 1000) * 1000L; 85 86 if (event_initialized(&c->overlay_timer)) 87 evtimer_del(&c->overlay_timer); 88 evtimer_set(&c->overlay_timer, server_client_overlay_timer, c); 89 if (delay != 0) 90 evtimer_add(&c->overlay_timer, &tv); 91 92 c->overlay_draw = drawcb; 93 c->overlay_key = keycb; 94 c->overlay_free = freecb; 95 c->overlay_data = data; 96 97 c->tty.flags |= (TTY_FREEZE|TTY_NOCURSOR); 98 server_redraw_client(c); 99 } 100 101 /* Clear overlay mode on client. */ 102 static void 103 server_client_clear_overlay(struct client *c) 104 { 105 if (c->overlay_draw == NULL) 106 return; 107 108 if (event_initialized(&c->overlay_timer)) 109 evtimer_del(&c->overlay_timer); 110 111 if (c->overlay_free != NULL) 112 c->overlay_free(c); 113 114 c->overlay_draw = NULL; 115 c->overlay_key = NULL; 116 117 c->tty.flags &= ~(TTY_FREEZE|TTY_NOCURSOR); 118 server_redraw_client(c); 119 } 120 121 /* Check if this client is inside this server. */ 122 int 123 server_client_check_nested(struct client *c) 124 { 125 struct environ_entry *envent; 126 struct window_pane *wp; 127 128 envent = environ_find(c->environ, "TMUX"); 129 if (envent == NULL || *envent->value == '\0') 130 return (0); 131 132 RB_FOREACH(wp, window_pane_tree, &all_window_panes) { 133 if (strcmp(wp->tty, c->ttyname) == 0) 134 return (1); 135 } 136 return (0); 137 } 138 139 /* Set client key table. */ 140 void 141 server_client_set_key_table(struct client *c, const char *name) 142 { 143 if (name == NULL) 144 name = server_client_get_key_table(c); 145 146 key_bindings_unref_table(c->keytable); 147 c->keytable = key_bindings_get_table(name, 1); 148 c->keytable->references++; 149 } 150 151 /* Get default key table. */ 152 const char * 153 server_client_get_key_table(struct client *c) 154 { 155 struct session *s = c->session; 156 const char *name; 157 158 if (s == NULL) 159 return ("root"); 160 161 name = options_get_string(s->options, "key-table"); 162 if (*name == '\0') 163 return ("root"); 164 return (name); 165 } 166 167 /* Is this table the default key table? */ 168 static int 169 server_client_is_default_key_table(struct client *c, struct key_table *table) 170 { 171 return (strcmp(table->name, server_client_get_key_table(c)) == 0); 172 } 173 174 /* Create a new client. */ 175 struct client * 176 server_client_create(int fd) 177 { 178 struct client *c; 179 180 setblocking(fd, 0); 181 182 c = xcalloc(1, sizeof *c); 183 c->references = 1; 184 c->peer = proc_add_peer(server_proc, fd, server_client_dispatch, c); 185 186 if (gettimeofday(&c->creation_time, NULL) != 0) 187 fatal("gettimeofday failed"); 188 memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time); 189 190 c->environ = environ_create(); 191 192 c->fd = -1; 193 c->cwd = NULL; 194 195 TAILQ_INIT(&c->queue); 196 197 c->stdin_data = evbuffer_new(); 198 if (c->stdin_data == NULL) 199 fatalx("out of memory"); 200 c->stdout_data = evbuffer_new(); 201 if (c->stdout_data == NULL) 202 fatalx("out of memory"); 203 c->stderr_data = evbuffer_new(); 204 if (c->stderr_data == NULL) 205 fatalx("out of memory"); 206 207 c->tty.fd = -1; 208 c->title = NULL; 209 210 c->session = NULL; 211 c->last_session = NULL; 212 213 c->tty.sx = 80; 214 c->tty.sy = 24; 215 216 status_init(c); 217 218 c->message_string = NULL; 219 TAILQ_INIT(&c->message_log); 220 221 c->prompt_string = NULL; 222 c->prompt_buffer = NULL; 223 c->prompt_index = 0; 224 225 c->flags |= CLIENT_FOCUSED; 226 227 c->keytable = key_bindings_get_table("root", 1); 228 c->keytable->references++; 229 230 evtimer_set(&c->repeat_timer, server_client_repeat_timer, c); 231 evtimer_set(&c->click_timer, server_client_click_timer, c); 232 233 TAILQ_INSERT_TAIL(&clients, c, entry); 234 log_debug("new client %p", c); 235 return (c); 236 } 237 238 /* Open client terminal if needed. */ 239 int 240 server_client_open(struct client *c, char **cause) 241 { 242 if (c->flags & CLIENT_CONTROL) 243 return (0); 244 245 if (strcmp(c->ttyname, "/dev/tty") == 0) { 246 *cause = xstrdup("can't use /dev/tty"); 247 return (-1); 248 } 249 250 if (!(c->flags & CLIENT_TERMINAL)) { 251 *cause = xstrdup("not a terminal"); 252 return (-1); 253 } 254 255 if (tty_open(&c->tty, cause) != 0) 256 return (-1); 257 258 return (0); 259 } 260 261 /* Lost a client. */ 262 void 263 server_client_lost(struct client *c) 264 { 265 struct message_entry *msg, *msg1; 266 267 c->flags |= CLIENT_DEAD; 268 269 server_client_clear_overlay(c); 270 status_prompt_clear(c); 271 status_message_clear(c); 272 273 if (c->stdin_callback != NULL) 274 c->stdin_callback(c, 1, c->stdin_callback_data); 275 276 TAILQ_REMOVE(&clients, c, entry); 277 log_debug("lost client %p", c); 278 279 /* 280 * If CLIENT_TERMINAL hasn't been set, then tty_init hasn't been called 281 * and tty_free might close an unrelated fd. 282 */ 283 if (c->flags & CLIENT_TERMINAL) 284 tty_free(&c->tty); 285 free(c->ttyname); 286 free(c->term); 287 288 evbuffer_free(c->stdin_data); 289 evbuffer_free(c->stdout_data); 290 if (c->stderr_data != c->stdout_data) 291 evbuffer_free(c->stderr_data); 292 293 status_free(c); 294 295 free(c->title); 296 free(__UNCONST(c->cwd)); 297 298 evtimer_del(&c->repeat_timer); 299 evtimer_del(&c->click_timer); 300 301 key_bindings_unref_table(c->keytable); 302 303 free(c->message_string); 304 if (event_initialized(&c->message_timer)) 305 evtimer_del(&c->message_timer); 306 TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) { 307 free(msg->msg); 308 TAILQ_REMOVE(&c->message_log, msg, entry); 309 free(msg); 310 } 311 312 free(c->prompt_saved); 313 free(c->prompt_string); 314 free(c->prompt_buffer); 315 316 format_lost_client(c); 317 environ_free(c->environ); 318 319 proc_remove_peer(c->peer); 320 c->peer = NULL; 321 322 server_client_unref(c); 323 324 server_add_accept(0); /* may be more file descriptors now */ 325 326 recalculate_sizes(); 327 server_check_unattached(); 328 server_update_socket(); 329 } 330 331 /* Remove reference from a client. */ 332 void 333 server_client_unref(struct client *c) 334 { 335 log_debug("unref client %p (%d references)", c, c->references); 336 337 c->references--; 338 if (c->references == 0) 339 event_once(-1, EV_TIMEOUT, server_client_free, c, NULL); 340 } 341 342 /* Free dead client. */ 343 static void 344 server_client_free(__unused int fd, __unused short events, void *arg) 345 { 346 struct client *c = arg; 347 348 log_debug("free client %p (%d references)", c, c->references); 349 350 if (!TAILQ_EMPTY(&c->queue)) 351 fatalx("queue not empty"); 352 353 if (c->references == 0) { 354 free(__UNCONST(c->name)); 355 free(c); 356 } 357 } 358 359 /* Suspend a client. */ 360 void 361 server_client_suspend(struct client *c) 362 { 363 struct session *s = c->session; 364 365 if (s == NULL || (c->flags & CLIENT_DETACHING)) 366 return; 367 368 tty_stop_tty(&c->tty); 369 c->flags |= CLIENT_SUSPENDED; 370 proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0); 371 } 372 373 /* Detach a client. */ 374 void 375 server_client_detach(struct client *c, enum msgtype msgtype) 376 { 377 struct session *s = c->session; 378 379 if (s == NULL || (c->flags & CLIENT_DETACHING)) 380 return; 381 382 c->flags |= CLIENT_DETACHING; 383 notify_client("client-detached", c); 384 proc_send(c->peer, msgtype, -1, s->name, strlen(s->name) + 1); 385 } 386 387 /* Execute command to replace a client. */ 388 void 389 server_client_exec(struct client *c, const char *cmd) 390 { 391 struct session *s = c->session; 392 char *msg; 393 const char *shell; 394 size_t cmdsize, shellsize; 395 396 if (*cmd == '\0') 397 return; 398 cmdsize = strlen(cmd) + 1; 399 400 if (s != NULL) 401 shell = options_get_string(s->options, "default-shell"); 402 else 403 shell = options_get_string(global_s_options, "default-shell"); 404 shellsize = strlen(shell) + 1; 405 406 msg = xmalloc(cmdsize + shellsize); 407 memcpy(msg, cmd, cmdsize); 408 memcpy(msg + cmdsize, shell, shellsize); 409 410 proc_send(c->peer, MSG_EXEC, -1, msg, cmdsize + shellsize); 411 free(msg); 412 } 413 414 /* Check for mouse keys. */ 415 static key_code 416 server_client_check_mouse(struct client *c, struct key_event *event) 417 { 418 struct mouse_event *m = &event->m; 419 struct session *s = c->session; 420 struct winlink *wl; 421 struct window_pane *wp; 422 u_int x, y, b, sx, sy, px, py; 423 int flag; 424 key_code key; 425 struct timeval tv; 426 struct style_range *sr; 427 enum { NOTYPE, 428 MOVE, 429 DOWN, 430 UP, 431 DRAG, 432 WHEEL, 433 DOUBLE, 434 TRIPLE } type = NOTYPE; 435 enum { NOWHERE, 436 PANE, 437 STATUS, 438 STATUS_LEFT, 439 STATUS_RIGHT, 440 STATUS_DEFAULT, 441 BORDER } where = NOWHERE; 442 443 log_debug("%s mouse %02x at %u,%u (last %u,%u) (%d)", c->name, m->b, 444 m->x, m->y, m->lx, m->ly, c->tty.mouse_drag_flag); 445 446 /* What type of event is this? */ 447 if ((m->sgr_type != ' ' && 448 MOUSE_DRAG(m->sgr_b) && 449 MOUSE_BUTTONS(m->sgr_b) == 3) || 450 (m->sgr_type == ' ' && 451 MOUSE_DRAG(m->b) && 452 MOUSE_BUTTONS(m->b) == 3 && 453 MOUSE_BUTTONS(m->lb) == 3)) { 454 type = MOVE; 455 x = m->x, y = m->y, b = 0; 456 log_debug("move at %u,%u", x, y); 457 } else if (MOUSE_DRAG(m->b)) { 458 type = DRAG; 459 if (c->tty.mouse_drag_flag) { 460 x = m->x, y = m->y, b = m->b; 461 if (x == m->lx && y == m->ly) 462 return (KEYC_UNKNOWN); 463 log_debug("drag update at %u,%u", x, y); 464 } else { 465 x = m->lx, y = m->ly, b = m->lb; 466 log_debug("drag start at %u,%u", x, y); 467 } 468 } else if (MOUSE_WHEEL(m->b)) { 469 type = WHEEL; 470 x = m->x, y = m->y, b = m->b; 471 log_debug("wheel at %u,%u", x, y); 472 } else if (MOUSE_RELEASE(m->b)) { 473 type = UP; 474 x = m->x, y = m->y, b = m->lb; 475 log_debug("up at %u,%u", x, y); 476 } else { 477 if (c->flags & CLIENT_DOUBLECLICK) { 478 evtimer_del(&c->click_timer); 479 c->flags &= ~CLIENT_DOUBLECLICK; 480 if (m->b == c->click_button) { 481 type = DOUBLE; 482 x = m->x, y = m->y, b = m->b; 483 log_debug("double-click at %u,%u", x, y); 484 flag = CLIENT_TRIPLECLICK; 485 goto add_timer; 486 } 487 } else if (c->flags & CLIENT_TRIPLECLICK) { 488 evtimer_del(&c->click_timer); 489 c->flags &= ~CLIENT_TRIPLECLICK; 490 if (m->b == c->click_button) { 491 type = TRIPLE; 492 x = m->x, y = m->y, b = m->b; 493 log_debug("triple-click at %u,%u", x, y); 494 goto have_event; 495 } 496 } 497 498 type = DOWN; 499 x = m->x, y = m->y, b = m->b; 500 log_debug("down at %u,%u", x, y); 501 flag = CLIENT_DOUBLECLICK; 502 503 add_timer: 504 if (KEYC_CLICK_TIMEOUT != 0) { 505 c->flags |= flag; 506 c->click_button = m->b; 507 508 tv.tv_sec = KEYC_CLICK_TIMEOUT / 1000; 509 tv.tv_usec = (KEYC_CLICK_TIMEOUT % 1000) * 1000L; 510 evtimer_del(&c->click_timer); 511 evtimer_add(&c->click_timer, &tv); 512 } 513 } 514 515 have_event: 516 if (type == NOTYPE) 517 return (KEYC_UNKNOWN); 518 519 /* Save the session. */ 520 m->s = s->id; 521 m->w = -1; 522 523 /* Is this on the status line? */ 524 m->statusat = status_at_line(c); 525 m->statuslines = status_line_size(c); 526 if (m->statusat != -1 && 527 y >= (u_int)m->statusat && 528 y < m->statusat + m->statuslines) { 529 sr = status_get_range(c, x, y - m->statusat); 530 if (sr == NULL) { 531 where = STATUS_DEFAULT; 532 } else { 533 switch (sr->type) { 534 case STYLE_RANGE_NONE: 535 return (KEYC_UNKNOWN); 536 case STYLE_RANGE_LEFT: 537 where = STATUS_LEFT; 538 break; 539 case STYLE_RANGE_RIGHT: 540 where = STATUS_RIGHT; 541 break; 542 case STYLE_RANGE_WINDOW: 543 wl = winlink_find_by_index(&s->windows, sr->argument); 544 if (wl == NULL) 545 return (KEYC_UNKNOWN); 546 m->w = wl->window->id; 547 548 where = STATUS; 549 break; 550 } 551 } 552 } 553 554 /* Not on status line. Adjust position and check for border or pane. */ 555 if (where == NOWHERE) { 556 px = x; 557 if (m->statusat == 0 && y >= m->statuslines) 558 py = y - m->statuslines; 559 else if (m->statusat > 0 && y >= (u_int)m->statusat) 560 py = m->statusat - 1; 561 else 562 py = y; 563 564 tty_window_offset(&c->tty, &m->ox, &m->oy, &sx, &sy); 565 log_debug("mouse window @%u at %u,%u (%ux%u)", 566 s->curw->window->id, m->ox, m->oy, sx, sy); 567 if (px > sx || py > sy) 568 return (KEYC_UNKNOWN); 569 px = px + m->ox; 570 py = py + m->oy; 571 572 /* Try the pane borders if not zoomed. */ 573 if (~s->curw->window->flags & WINDOW_ZOOMED) { 574 TAILQ_FOREACH(wp, &s->curw->window->panes, entry) { 575 if ((wp->xoff + wp->sx == px && 576 wp->yoff <= 1 + py && 577 wp->yoff + wp->sy >= py) || 578 (wp->yoff + wp->sy == py && 579 wp->xoff <= 1 + px && 580 wp->xoff + wp->sx >= px)) 581 break; 582 } 583 if (wp != NULL) 584 where = BORDER; 585 } 586 587 /* Otherwise try inside the pane. */ 588 if (where == NOWHERE) { 589 wp = window_get_active_at(s->curw->window, px, py); 590 if (wp != NULL) 591 where = PANE; 592 } 593 594 if (where == NOWHERE) 595 return (KEYC_UNKNOWN); 596 if (where == PANE) 597 log_debug("mouse %u,%u on pane %%%u", x, y, wp->id); 598 else if (where == BORDER) 599 log_debug("mouse on pane %%%u border", wp->id); 600 m->wp = wp->id; 601 m->w = wp->window->id; 602 } else 603 m->wp = -1; 604 605 /* Stop dragging if needed. */ 606 if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag) { 607 if (c->tty.mouse_drag_release != NULL) 608 c->tty.mouse_drag_release(c, m); 609 610 c->tty.mouse_drag_update = NULL; 611 c->tty.mouse_drag_release = NULL; 612 613 /* 614 * End a mouse drag by passing a MouseDragEnd key corresponding 615 * to the button that started the drag. 616 */ 617 switch (c->tty.mouse_drag_flag) { 618 case 1: 619 if (where == PANE) 620 key = KEYC_MOUSEDRAGEND1_PANE; 621 if (where == STATUS) 622 key = KEYC_MOUSEDRAGEND1_STATUS; 623 if (where == STATUS_LEFT) 624 key = KEYC_MOUSEDRAGEND1_STATUS_LEFT; 625 if (where == STATUS_RIGHT) 626 key = KEYC_MOUSEDRAGEND1_STATUS_RIGHT; 627 if (where == STATUS_DEFAULT) 628 key = KEYC_MOUSEDRAGEND1_STATUS_DEFAULT; 629 if (where == BORDER) 630 key = KEYC_MOUSEDRAGEND1_BORDER; 631 break; 632 case 2: 633 if (where == PANE) 634 key = KEYC_MOUSEDRAGEND2_PANE; 635 if (where == STATUS) 636 key = KEYC_MOUSEDRAGEND2_STATUS; 637 if (where == STATUS_LEFT) 638 key = KEYC_MOUSEDRAGEND2_STATUS_LEFT; 639 if (where == STATUS_RIGHT) 640 key = KEYC_MOUSEDRAGEND2_STATUS_RIGHT; 641 if (where == STATUS_DEFAULT) 642 key = KEYC_MOUSEDRAGEND2_STATUS_DEFAULT; 643 if (where == BORDER) 644 key = KEYC_MOUSEDRAGEND2_BORDER; 645 break; 646 case 3: 647 if (where == PANE) 648 key = KEYC_MOUSEDRAGEND3_PANE; 649 if (where == STATUS) 650 key = KEYC_MOUSEDRAGEND3_STATUS; 651 if (where == STATUS_LEFT) 652 key = KEYC_MOUSEDRAGEND3_STATUS_LEFT; 653 if (where == STATUS_RIGHT) 654 key = KEYC_MOUSEDRAGEND3_STATUS_RIGHT; 655 if (where == STATUS_DEFAULT) 656 key = KEYC_MOUSEDRAGEND3_STATUS_DEFAULT; 657 if (where == BORDER) 658 key = KEYC_MOUSEDRAGEND3_BORDER; 659 break; 660 default: 661 key = KEYC_MOUSE; 662 break; 663 } 664 c->tty.mouse_drag_flag = 0; 665 666 return (key); 667 } 668 669 /* Convert to a key binding. */ 670 key = KEYC_UNKNOWN; 671 switch (type) { 672 case NOTYPE: 673 break; 674 case MOVE: 675 if (where == PANE) 676 key = KEYC_MOUSEMOVE_PANE; 677 if (where == STATUS) 678 key = KEYC_MOUSEMOVE_STATUS; 679 if (where == STATUS_LEFT) 680 key = KEYC_MOUSEMOVE_STATUS_LEFT; 681 if (where == STATUS_RIGHT) 682 key = KEYC_MOUSEMOVE_STATUS_RIGHT; 683 if (where == STATUS_DEFAULT) 684 key = KEYC_MOUSEMOVE_STATUS_DEFAULT; 685 if (where == BORDER) 686 key = KEYC_MOUSEMOVE_BORDER; 687 break; 688 case DRAG: 689 if (c->tty.mouse_drag_update != NULL) 690 key = KEYC_DRAGGING; 691 else { 692 switch (MOUSE_BUTTONS(b)) { 693 case 0: 694 if (where == PANE) 695 key = KEYC_MOUSEDRAG1_PANE; 696 if (where == STATUS) 697 key = KEYC_MOUSEDRAG1_STATUS; 698 if (where == STATUS_LEFT) 699 key = KEYC_MOUSEDRAG1_STATUS_LEFT; 700 if (where == STATUS_RIGHT) 701 key = KEYC_MOUSEDRAG1_STATUS_RIGHT; 702 if (where == STATUS_DEFAULT) 703 key = KEYC_MOUSEDRAG1_STATUS_DEFAULT; 704 if (where == BORDER) 705 key = KEYC_MOUSEDRAG1_BORDER; 706 break; 707 case 1: 708 if (where == PANE) 709 key = KEYC_MOUSEDRAG2_PANE; 710 if (where == STATUS) 711 key = KEYC_MOUSEDRAG2_STATUS; 712 if (where == STATUS_LEFT) 713 key = KEYC_MOUSEDRAG2_STATUS_LEFT; 714 if (where == STATUS_RIGHT) 715 key = KEYC_MOUSEDRAG2_STATUS_RIGHT; 716 if (where == STATUS_DEFAULT) 717 key = KEYC_MOUSEDRAG2_STATUS_DEFAULT; 718 if (where == BORDER) 719 key = KEYC_MOUSEDRAG2_BORDER; 720 break; 721 case 2: 722 if (where == PANE) 723 key = KEYC_MOUSEDRAG3_PANE; 724 if (where == STATUS) 725 key = KEYC_MOUSEDRAG3_STATUS; 726 if (where == STATUS_LEFT) 727 key = KEYC_MOUSEDRAG3_STATUS_LEFT; 728 if (where == STATUS_RIGHT) 729 key = KEYC_MOUSEDRAG3_STATUS_RIGHT; 730 if (where == STATUS_DEFAULT) 731 key = KEYC_MOUSEDRAG3_STATUS_DEFAULT; 732 if (where == BORDER) 733 key = KEYC_MOUSEDRAG3_BORDER; 734 break; 735 } 736 } 737 738 /* 739 * Begin a drag by setting the flag to a non-zero value that 740 * corresponds to the mouse button in use. 741 */ 742 c->tty.mouse_drag_flag = MOUSE_BUTTONS(b) + 1; 743 break; 744 case WHEEL: 745 if (MOUSE_BUTTONS(b) == MOUSE_WHEEL_UP) { 746 if (where == PANE) 747 key = KEYC_WHEELUP_PANE; 748 if (where == STATUS) 749 key = KEYC_WHEELUP_STATUS; 750 if (where == STATUS_LEFT) 751 key = KEYC_WHEELUP_STATUS_LEFT; 752 if (where == STATUS_RIGHT) 753 key = KEYC_WHEELUP_STATUS_RIGHT; 754 if (where == STATUS_DEFAULT) 755 key = KEYC_WHEELUP_STATUS_DEFAULT; 756 if (where == BORDER) 757 key = KEYC_WHEELUP_BORDER; 758 } else { 759 if (where == PANE) 760 key = KEYC_WHEELDOWN_PANE; 761 if (where == STATUS) 762 key = KEYC_WHEELDOWN_STATUS; 763 if (where == STATUS_LEFT) 764 key = KEYC_WHEELDOWN_STATUS_LEFT; 765 if (where == STATUS_RIGHT) 766 key = KEYC_WHEELDOWN_STATUS_RIGHT; 767 if (where == STATUS_DEFAULT) 768 key = KEYC_WHEELDOWN_STATUS_DEFAULT; 769 if (where == BORDER) 770 key = KEYC_WHEELDOWN_BORDER; 771 } 772 break; 773 case UP: 774 switch (MOUSE_BUTTONS(b)) { 775 case 0: 776 if (where == PANE) 777 key = KEYC_MOUSEUP1_PANE; 778 if (where == STATUS) 779 key = KEYC_MOUSEUP1_STATUS; 780 if (where == STATUS_LEFT) 781 key = KEYC_MOUSEUP1_STATUS_LEFT; 782 if (where == STATUS_RIGHT) 783 key = KEYC_MOUSEUP1_STATUS_RIGHT; 784 if (where == STATUS_DEFAULT) 785 key = KEYC_MOUSEUP1_STATUS_DEFAULT; 786 if (where == BORDER) 787 key = KEYC_MOUSEUP1_BORDER; 788 break; 789 case 1: 790 if (where == PANE) 791 key = KEYC_MOUSEUP2_PANE; 792 if (where == STATUS) 793 key = KEYC_MOUSEUP2_STATUS; 794 if (where == STATUS_LEFT) 795 key = KEYC_MOUSEUP2_STATUS_LEFT; 796 if (where == STATUS_RIGHT) 797 key = KEYC_MOUSEUP2_STATUS_RIGHT; 798 if (where == STATUS_DEFAULT) 799 key = KEYC_MOUSEUP2_STATUS_DEFAULT; 800 if (where == BORDER) 801 key = KEYC_MOUSEUP2_BORDER; 802 break; 803 case 2: 804 if (where == PANE) 805 key = KEYC_MOUSEUP3_PANE; 806 if (where == STATUS) 807 key = KEYC_MOUSEUP3_STATUS; 808 if (where == STATUS_LEFT) 809 key = KEYC_MOUSEUP3_STATUS_LEFT; 810 if (where == STATUS_RIGHT) 811 key = KEYC_MOUSEUP3_STATUS_RIGHT; 812 if (where == STATUS_DEFAULT) 813 key = KEYC_MOUSEUP3_STATUS_DEFAULT; 814 if (where == BORDER) 815 key = KEYC_MOUSEUP3_BORDER; 816 break; 817 } 818 break; 819 case DOWN: 820 switch (MOUSE_BUTTONS(b)) { 821 case 0: 822 if (where == PANE) 823 key = KEYC_MOUSEDOWN1_PANE; 824 if (where == STATUS) 825 key = KEYC_MOUSEDOWN1_STATUS; 826 if (where == STATUS_LEFT) 827 key = KEYC_MOUSEDOWN1_STATUS_LEFT; 828 if (where == STATUS_RIGHT) 829 key = KEYC_MOUSEDOWN1_STATUS_RIGHT; 830 if (where == STATUS_DEFAULT) 831 key = KEYC_MOUSEDOWN1_STATUS_DEFAULT; 832 if (where == BORDER) 833 key = KEYC_MOUSEDOWN1_BORDER; 834 break; 835 case 1: 836 if (where == PANE) 837 key = KEYC_MOUSEDOWN2_PANE; 838 if (where == STATUS) 839 key = KEYC_MOUSEDOWN2_STATUS; 840 if (where == STATUS_LEFT) 841 key = KEYC_MOUSEDOWN2_STATUS_LEFT; 842 if (where == STATUS_RIGHT) 843 key = KEYC_MOUSEDOWN2_STATUS_RIGHT; 844 if (where == STATUS_DEFAULT) 845 key = KEYC_MOUSEDOWN2_STATUS_DEFAULT; 846 if (where == BORDER) 847 key = KEYC_MOUSEDOWN2_BORDER; 848 break; 849 case 2: 850 if (where == PANE) 851 key = KEYC_MOUSEDOWN3_PANE; 852 if (where == STATUS) 853 key = KEYC_MOUSEDOWN3_STATUS; 854 if (where == STATUS_LEFT) 855 key = KEYC_MOUSEDOWN3_STATUS_LEFT; 856 if (where == STATUS_RIGHT) 857 key = KEYC_MOUSEDOWN3_STATUS_RIGHT; 858 if (where == STATUS_DEFAULT) 859 key = KEYC_MOUSEDOWN3_STATUS_DEFAULT; 860 if (where == BORDER) 861 key = KEYC_MOUSEDOWN3_BORDER; 862 break; 863 } 864 break; 865 case DOUBLE: 866 switch (MOUSE_BUTTONS(b)) { 867 case 0: 868 if (where == PANE) 869 key = KEYC_DOUBLECLICK1_PANE; 870 if (where == STATUS) 871 key = KEYC_DOUBLECLICK1_STATUS; 872 if (where == STATUS_LEFT) 873 key = KEYC_DOUBLECLICK1_STATUS_LEFT; 874 if (where == STATUS_RIGHT) 875 key = KEYC_DOUBLECLICK1_STATUS_RIGHT; 876 if (where == STATUS_DEFAULT) 877 key = KEYC_DOUBLECLICK1_STATUS_DEFAULT; 878 if (where == BORDER) 879 key = KEYC_DOUBLECLICK1_BORDER; 880 break; 881 case 1: 882 if (where == PANE) 883 key = KEYC_DOUBLECLICK2_PANE; 884 if (where == STATUS) 885 key = KEYC_DOUBLECLICK2_STATUS; 886 if (where == STATUS_LEFT) 887 key = KEYC_DOUBLECLICK2_STATUS_LEFT; 888 if (where == STATUS_RIGHT) 889 key = KEYC_DOUBLECLICK2_STATUS_RIGHT; 890 if (where == STATUS_DEFAULT) 891 key = KEYC_DOUBLECLICK2_STATUS_DEFAULT; 892 if (where == BORDER) 893 key = KEYC_DOUBLECLICK2_BORDER; 894 break; 895 case 2: 896 if (where == PANE) 897 key = KEYC_DOUBLECLICK3_PANE; 898 if (where == STATUS) 899 key = KEYC_DOUBLECLICK3_STATUS; 900 if (where == STATUS_LEFT) 901 key = KEYC_DOUBLECLICK3_STATUS_LEFT; 902 if (where == STATUS_RIGHT) 903 key = KEYC_DOUBLECLICK3_STATUS_RIGHT; 904 if (where == STATUS_DEFAULT) 905 key = KEYC_DOUBLECLICK3_STATUS_DEFAULT; 906 if (where == BORDER) 907 key = KEYC_DOUBLECLICK3_BORDER; 908 break; 909 } 910 break; 911 case TRIPLE: 912 switch (MOUSE_BUTTONS(b)) { 913 case 0: 914 if (where == PANE) 915 key = KEYC_TRIPLECLICK1_PANE; 916 if (where == STATUS) 917 key = KEYC_TRIPLECLICK1_STATUS; 918 if (where == STATUS_LEFT) 919 key = KEYC_TRIPLECLICK1_STATUS_LEFT; 920 if (where == STATUS_RIGHT) 921 key = KEYC_TRIPLECLICK1_STATUS_RIGHT; 922 if (where == STATUS_DEFAULT) 923 key = KEYC_TRIPLECLICK1_STATUS_DEFAULT; 924 if (where == BORDER) 925 key = KEYC_TRIPLECLICK1_BORDER; 926 break; 927 case 1: 928 if (where == PANE) 929 key = KEYC_TRIPLECLICK2_PANE; 930 if (where == STATUS) 931 key = KEYC_TRIPLECLICK2_STATUS; 932 if (where == STATUS_LEFT) 933 key = KEYC_TRIPLECLICK2_STATUS_LEFT; 934 if (where == STATUS_RIGHT) 935 key = KEYC_TRIPLECLICK2_STATUS_RIGHT; 936 if (where == STATUS_DEFAULT) 937 key = KEYC_TRIPLECLICK2_STATUS_DEFAULT; 938 if (where == BORDER) 939 key = KEYC_TRIPLECLICK2_BORDER; 940 break; 941 case 2: 942 if (where == PANE) 943 key = KEYC_TRIPLECLICK3_PANE; 944 if (where == STATUS) 945 key = KEYC_TRIPLECLICK3_STATUS; 946 if (where == STATUS_LEFT) 947 key = KEYC_TRIPLECLICK3_STATUS_LEFT; 948 if (where == STATUS_RIGHT) 949 key = KEYC_TRIPLECLICK3_STATUS_RIGHT; 950 if (where == STATUS_DEFAULT) 951 key = KEYC_TRIPLECLICK3_STATUS_DEFAULT; 952 if (where == BORDER) 953 key = KEYC_TRIPLECLICK3_BORDER; 954 break; 955 } 956 break; 957 } 958 if (key == KEYC_UNKNOWN) 959 return (KEYC_UNKNOWN); 960 961 /* Apply modifiers if any. */ 962 if (b & MOUSE_MASK_META) 963 key |= KEYC_ESCAPE; 964 if (b & MOUSE_MASK_CTRL) 965 key |= KEYC_CTRL; 966 if (b & MOUSE_MASK_SHIFT) 967 key |= KEYC_SHIFT; 968 969 return (key); 970 } 971 972 /* Is this fast enough to probably be a paste? */ 973 static int 974 server_client_assume_paste(struct session *s) 975 { 976 struct timeval tv; 977 int t; 978 979 if ((t = options_get_number(s->options, "assume-paste-time")) == 0) 980 return (0); 981 982 timersub(&s->activity_time, &s->last_activity_time, &tv); 983 if (tv.tv_sec == 0 && tv.tv_usec < t * 1000) { 984 log_debug("session %s pasting (flag %d)", s->name, 985 !!(s->flags & SESSION_PASTING)); 986 if (s->flags & SESSION_PASTING) 987 return (1); 988 s->flags |= SESSION_PASTING; 989 return (0); 990 } 991 log_debug("session %s not pasting", s->name); 992 s->flags &= ~SESSION_PASTING; 993 return (0); 994 } 995 996 /* 997 * Handle data key input from client. This owns and can modify the key event it 998 * is given and is responsible for freeing it. 999 */ 1000 static enum cmd_retval 1001 server_client_key_callback(struct cmdq_item *item, void *data) 1002 { 1003 struct client *c = item->client; 1004 struct key_event *event = data; 1005 key_code key = event->key; 1006 struct mouse_event *m = &event->m; 1007 struct session *s = c->session; 1008 struct winlink *wl; 1009 struct window_pane *wp; 1010 struct window_mode_entry *wme; 1011 struct timeval tv; 1012 struct key_table *table, *first; 1013 struct key_binding *bd; 1014 int xtimeout, flags; 1015 struct cmd_find_state fs; 1016 key_code key0; 1017 1018 /* Check the client is good to accept input. */ 1019 if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) 1020 goto out; 1021 wl = s->curw; 1022 1023 /* Update the activity timer. */ 1024 if (gettimeofday(&c->activity_time, NULL) != 0) 1025 fatal("gettimeofday failed"); 1026 session_update_activity(s, &c->activity_time); 1027 1028 /* Check for mouse keys. */ 1029 m->valid = 0; 1030 if (key == KEYC_MOUSE) { 1031 if (c->flags & CLIENT_READONLY) 1032 goto out; 1033 key = server_client_check_mouse(c, event); 1034 if (key == KEYC_UNKNOWN) 1035 goto out; 1036 1037 m->valid = 1; 1038 m->key = key; 1039 1040 /* 1041 * Mouse drag is in progress, so fire the callback (now that 1042 * the mouse event is valid). 1043 */ 1044 if (key == KEYC_DRAGGING) { 1045 c->tty.mouse_drag_update(c, m); 1046 goto out; 1047 } 1048 } 1049 1050 /* Find affected pane. */ 1051 if (!KEYC_IS_MOUSE(key) || cmd_find_from_mouse(&fs, m, 0) != 0) 1052 cmd_find_from_session(&fs, s, 0); 1053 wp = fs.wp; 1054 1055 /* Forward mouse keys if disabled. */ 1056 if (KEYC_IS_MOUSE(key) && !options_get_number(s->options, "mouse")) 1057 goto forward_key; 1058 1059 /* Treat everything as a regular key when pasting is detected. */ 1060 if (!KEYC_IS_MOUSE(key) && server_client_assume_paste(s)) 1061 goto forward_key; 1062 1063 /* 1064 * Work out the current key table. If the pane is in a mode, use 1065 * the mode table instead of the default key table. 1066 */ 1067 if (server_client_is_default_key_table(c, c->keytable) && 1068 wp != NULL && 1069 (wme = TAILQ_FIRST(&wp->modes)) != NULL && 1070 wme->mode->key_table != NULL) 1071 table = key_bindings_get_table(wme->mode->key_table(wme), 1); 1072 else 1073 table = c->keytable; 1074 first = table; 1075 1076 table_changed: 1077 /* 1078 * The prefix always takes precedence and forces a switch to the prefix 1079 * table, unless we are already there. 1080 */ 1081 key0 = (key & ~KEYC_XTERM); 1082 if ((key0 == (key_code)options_get_number(s->options, "prefix") || 1083 key0 == (key_code)options_get_number(s->options, "prefix2")) && 1084 strcmp(table->name, "prefix") != 0) { 1085 server_client_set_key_table(c, "prefix"); 1086 server_status_client(c); 1087 goto out; 1088 } 1089 flags = c->flags; 1090 1091 try_again: 1092 /* Log key table. */ 1093 if (wp == NULL) 1094 log_debug("key table %s (no pane)", table->name); 1095 else 1096 log_debug("key table %s (pane %%%u)", table->name, wp->id); 1097 if (c->flags & CLIENT_REPEAT) 1098 log_debug("currently repeating"); 1099 1100 /* Try to see if there is a key binding in the current table. */ 1101 bd = key_bindings_get(table, key0); 1102 if (bd != NULL) { 1103 /* 1104 * Key was matched in this table. If currently repeating but a 1105 * non-repeating binding was found, stop repeating and try 1106 * again in the root table. 1107 */ 1108 if ((c->flags & CLIENT_REPEAT) && 1109 (~bd->flags & KEY_BINDING_REPEAT)) { 1110 log_debug("found in key table %s (not repeating)", 1111 table->name); 1112 server_client_set_key_table(c, NULL); 1113 first = table = c->keytable; 1114 c->flags &= ~CLIENT_REPEAT; 1115 server_status_client(c); 1116 goto table_changed; 1117 } 1118 log_debug("found in key table %s", table->name); 1119 1120 /* 1121 * Take a reference to this table to make sure the key binding 1122 * doesn't disappear. 1123 */ 1124 table->references++; 1125 1126 /* 1127 * If this is a repeating key, start the timer. Otherwise reset 1128 * the client back to the root table. 1129 */ 1130 xtimeout = options_get_number(s->options, "repeat-time"); 1131 if (xtimeout != 0 && (bd->flags & KEY_BINDING_REPEAT)) { 1132 c->flags |= CLIENT_REPEAT; 1133 1134 tv.tv_sec = xtimeout / 1000; 1135 tv.tv_usec = (xtimeout % 1000) * 1000L; 1136 evtimer_del(&c->repeat_timer); 1137 evtimer_add(&c->repeat_timer, &tv); 1138 } else { 1139 c->flags &= ~CLIENT_REPEAT; 1140 server_client_set_key_table(c, NULL); 1141 } 1142 server_status_client(c); 1143 1144 /* Execute the key binding. */ 1145 key_bindings_dispatch(bd, item, c, m, &fs); 1146 key_bindings_unref_table(table); 1147 goto out; 1148 } 1149 1150 /* 1151 * No match, try the ANY key. 1152 */ 1153 if (key0 != KEYC_ANY) { 1154 key0 = KEYC_ANY; 1155 goto try_again; 1156 } 1157 1158 /* 1159 * No match in this table. If not in the root table or if repeating, 1160 * switch the client back to the root table and try again. 1161 */ 1162 log_debug("not found in key table %s", table->name); 1163 if (!server_client_is_default_key_table(c, table) || 1164 (c->flags & CLIENT_REPEAT)) { 1165 log_debug("trying in root table"); 1166 server_client_set_key_table(c, NULL); 1167 table = c->keytable; 1168 if (c->flags & CLIENT_REPEAT) 1169 first = table; 1170 c->flags &= ~CLIENT_REPEAT; 1171 server_status_client(c); 1172 goto table_changed; 1173 } 1174 1175 /* 1176 * No match in the root table either. If this wasn't the first table 1177 * tried, don't pass the key to the pane. 1178 */ 1179 if (first != table && (~flags & CLIENT_REPEAT)) { 1180 server_client_set_key_table(c, NULL); 1181 server_status_client(c); 1182 goto out; 1183 } 1184 1185 forward_key: 1186 if (c->flags & CLIENT_READONLY) 1187 goto out; 1188 if (wp != NULL) 1189 window_pane_key(wp, c, s, wl, key, m); 1190 1191 out: 1192 free(event); 1193 return (CMD_RETURN_NORMAL); 1194 } 1195 1196 /* Handle a key event. */ 1197 int 1198 server_client_handle_key(struct client *c, struct key_event *event) 1199 { 1200 struct session *s = c->session; 1201 struct cmdq_item *item; 1202 1203 /* Check the client is good to accept input. */ 1204 if (s == NULL || (c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0) 1205 return (0); 1206 1207 /* 1208 * Key presses in overlay mode and the command prompt are a special 1209 * case. The queue might be blocked so they need to be processed 1210 * immediately rather than queued. 1211 */ 1212 if (~c->flags & CLIENT_READONLY) { 1213 status_message_clear(c); 1214 if (c->prompt_string != NULL) { 1215 if (status_prompt_key(c, event->key) == 0) 1216 return (0); 1217 } 1218 if (c->overlay_key != NULL) { 1219 switch (c->overlay_key(c, event)) { 1220 case 0: 1221 return (0); 1222 case 1: 1223 server_client_clear_overlay(c); 1224 return (0); 1225 } 1226 } 1227 server_client_clear_overlay(c); 1228 } 1229 1230 /* 1231 * Add the key to the queue so it happens after any commands queued by 1232 * previous keys. 1233 */ 1234 item = cmdq_get_callback(server_client_key_callback, event); 1235 cmdq_append(c, item); 1236 return (1); 1237 } 1238 1239 /* Client functions that need to happen every loop. */ 1240 void 1241 server_client_loop(void) 1242 { 1243 struct client *c; 1244 struct window *w; 1245 struct window_pane *wp; 1246 struct winlink *wl; 1247 struct session *s; 1248 int focus; 1249 1250 TAILQ_FOREACH(c, &clients, entry) { 1251 server_client_check_exit(c); 1252 if (c->session != NULL) { 1253 server_client_check_redraw(c); 1254 server_client_reset_state(c); 1255 } 1256 } 1257 1258 /* 1259 * Any windows will have been redrawn as part of clients, so clear 1260 * their flags now. Also check pane focus and resize. 1261 */ 1262 focus = options_get_number(global_options, "focus-events"); 1263 RB_FOREACH(w, windows, &windows) { 1264 TAILQ_FOREACH(wl, &w->winlinks, wentry) { 1265 s = wl->session; 1266 if (s->attached != 0 && s->curw == wl) 1267 break; 1268 } 1269 TAILQ_FOREACH(wp, &w->panes, entry) { 1270 if (wp->fd != -1) { 1271 if (focus) 1272 server_client_check_focus(wp); 1273 if (wl != NULL) 1274 server_client_check_resize(wp); 1275 } 1276 wp->flags &= ~PANE_REDRAW; 1277 } 1278 check_window_name(w); 1279 } 1280 } 1281 1282 /* Check if we need to force a resize. */ 1283 static int 1284 server_client_resize_force(struct window_pane *wp) 1285 { 1286 struct timeval tv = { .tv_usec = 100000 }; 1287 struct winsize ws; 1288 1289 /* 1290 * If we are resizing to the same size as when we entered the loop 1291 * (that is, to the same size the application currently thinks it is), 1292 * tmux may have gone through several resizes internally and thrown 1293 * away parts of the screen. So we need the application to actually 1294 * redraw even though its final size has not changed. 1295 */ 1296 1297 if (wp->flags & PANE_RESIZEFORCE) { 1298 wp->flags &= ~PANE_RESIZEFORCE; 1299 return (0); 1300 } 1301 1302 if (wp->sx != wp->osx || 1303 wp->sy != wp->osy || 1304 wp->sx <= 1 || 1305 wp->sy <= 1) 1306 return (0); 1307 1308 memset(&ws, 0, sizeof ws); 1309 ws.ws_col = wp->sx; 1310 ws.ws_row = wp->sy - 1; 1311 if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) 1312 #ifdef __sun 1313 if (errno != EINVAL && errno != ENXIO) 1314 #endif 1315 fatal("ioctl failed"); 1316 log_debug("%s: %%%u forcing resize", __func__, wp->id); 1317 1318 evtimer_add(&wp->resize_timer, &tv); 1319 wp->flags |= PANE_RESIZEFORCE; 1320 return (1); 1321 } 1322 1323 /* Resize timer event. */ 1324 static void 1325 server_client_resize_event(__unused int fd, __unused short events, void *data) 1326 { 1327 struct window_pane *wp = data; 1328 struct winsize ws; 1329 1330 evtimer_del(&wp->resize_timer); 1331 1332 if (!(wp->flags & PANE_RESIZE)) 1333 return; 1334 if (server_client_resize_force(wp)) 1335 return; 1336 1337 memset(&ws, 0, sizeof ws); 1338 ws.ws_col = wp->sx; 1339 ws.ws_row = wp->sy; 1340 if (wp->fd != -1 && ioctl(wp->fd, TIOCSWINSZ, &ws) == -1) 1341 #ifdef __sun 1342 /* 1343 * Some versions of Solaris apparently can return an error when 1344 * resizing; don't know why this happens, can't reproduce on 1345 * other platforms and ignoring it doesn't seem to cause any 1346 * issues. 1347 */ 1348 if (errno != EINVAL && errno != ENXIO) 1349 #endif 1350 fatal("ioctl failed"); 1351 log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy); 1352 1353 wp->flags &= ~PANE_RESIZE; 1354 1355 wp->osx = wp->sx; 1356 wp->osy = wp->sy; 1357 } 1358 1359 /* Check if pane should be resized. */ 1360 static void 1361 server_client_check_resize(struct window_pane *wp) 1362 { 1363 struct timeval tv = { .tv_usec = 250000 }; 1364 1365 if (!(wp->flags & PANE_RESIZE)) 1366 return; 1367 log_debug("%s: %%%u resize to %u,%u", __func__, wp->id, wp->sx, wp->sy); 1368 1369 if (!event_initialized(&wp->resize_timer)) 1370 evtimer_set(&wp->resize_timer, server_client_resize_event, wp); 1371 1372 /* 1373 * The first resize should happen immediately, so if the timer is not 1374 * running, do it now. 1375 */ 1376 if (!evtimer_pending(&wp->resize_timer, NULL)) 1377 server_client_resize_event(-1, 0, wp); 1378 1379 /* 1380 * If the pane is in the alternate screen, let the timer expire and 1381 * resize to give the application a chance to redraw. If not, keep 1382 * pushing the timer back. 1383 */ 1384 if (wp->saved_grid != NULL && evtimer_pending(&wp->resize_timer, NULL)) 1385 return; 1386 evtimer_del(&wp->resize_timer); 1387 evtimer_add(&wp->resize_timer, &tv); 1388 } 1389 1390 /* Check whether pane should be focused. */ 1391 static void 1392 server_client_check_focus(struct window_pane *wp) 1393 { 1394 struct client *c; 1395 int push; 1396 1397 /* Do we need to push the focus state? */ 1398 push = wp->flags & PANE_FOCUSPUSH; 1399 wp->flags &= ~PANE_FOCUSPUSH; 1400 1401 /* If we're not the active pane in our window, we're not focused. */ 1402 if (wp->window->active != wp) 1403 goto not_focused; 1404 1405 /* If we're in a mode, we're not focused. */ 1406 if (wp->screen != &wp->base) 1407 goto not_focused; 1408 1409 /* 1410 * If our window is the current window in any focused clients with an 1411 * attached session, we're focused. 1412 */ 1413 TAILQ_FOREACH(c, &clients, entry) { 1414 if (c->session == NULL || !(c->flags & CLIENT_FOCUSED)) 1415 continue; 1416 if (c->session->attached == 0) 1417 continue; 1418 1419 if (c->session->curw->window == wp->window) 1420 goto focused; 1421 } 1422 1423 not_focused: 1424 if (push || (wp->flags & PANE_FOCUSED)) { 1425 if (wp->base.mode & MODE_FOCUSON) 1426 bufferevent_write(wp->event, "\033[O", 3); 1427 notify_pane("pane-focus-out", wp); 1428 } 1429 wp->flags &= ~PANE_FOCUSED; 1430 return; 1431 1432 focused: 1433 if (push || !(wp->flags & PANE_FOCUSED)) { 1434 if (wp->base.mode & MODE_FOCUSON) 1435 bufferevent_write(wp->event, "\033[I", 3); 1436 notify_pane("pane-focus-in", wp); 1437 session_update_activity(c->session, NULL); 1438 } 1439 wp->flags |= PANE_FOCUSED; 1440 } 1441 1442 /* 1443 * Update cursor position and mode settings. The scroll region and attributes 1444 * are cleared when idle (waiting for an event) as this is the most likely time 1445 * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a 1446 * compromise between excessive resets and likelihood of an interrupt. 1447 * 1448 * tty_region/tty_reset/tty_update_mode already take care of not resetting 1449 * things that are already in their default state. 1450 */ 1451 static void 1452 server_client_reset_state(struct client *c) 1453 { 1454 struct window *w = c->session->curw->window; 1455 struct window_pane *wp = w->active, *loop; 1456 struct screen *s = wp->screen; 1457 struct options *oo = c->session->options; 1458 int mode, cursor = 0; 1459 u_int cx = 0, cy = 0, ox, oy, sx, sy; 1460 1461 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1462 return; 1463 if (c->overlay_draw != NULL) 1464 return; 1465 mode = s->mode; 1466 1467 tty_region_off(&c->tty); 1468 tty_margin_off(&c->tty); 1469 1470 /* Move cursor to pane cursor and offset. */ 1471 cursor = 0; 1472 tty_window_offset(&c->tty, &ox, &oy, &sx, &sy); 1473 if (wp->xoff + s->cx >= ox && wp->xoff + s->cx <= ox + sx && 1474 wp->yoff + s->cy >= oy && wp->yoff + s->cy <= oy + sy) { 1475 cursor = 1; 1476 1477 cx = wp->xoff + s->cx - ox; 1478 cy = wp->yoff + s->cy - oy; 1479 1480 if (status_at_line(c) == 0) 1481 cy += status_line_size(c); 1482 } 1483 if (!cursor) 1484 mode &= ~MODE_CURSOR; 1485 tty_cursor(&c->tty, cx, cy); 1486 1487 /* 1488 * Set mouse mode if requested. To support dragging, always use button 1489 * mode. 1490 */ 1491 if (options_get_number(oo, "mouse")) { 1492 mode &= ~ALL_MOUSE_MODES; 1493 TAILQ_FOREACH(loop, &w->panes, entry) { 1494 if (loop->screen->mode & MODE_MOUSE_ALL) 1495 mode |= MODE_MOUSE_ALL; 1496 } 1497 if (~mode & MODE_MOUSE_ALL) 1498 mode |= MODE_MOUSE_BUTTON; 1499 } 1500 1501 /* Clear bracketed paste mode if at the prompt. */ 1502 if (c->prompt_string != NULL) 1503 mode &= ~MODE_BRACKETPASTE; 1504 1505 /* Set the terminal mode and reset attributes. */ 1506 tty_update_mode(&c->tty, mode, s); 1507 tty_reset(&c->tty); 1508 } 1509 1510 /* Repeat time callback. */ 1511 static void 1512 server_client_repeat_timer(__unused int fd, __unused short events, void *data) 1513 { 1514 struct client *c = data; 1515 1516 if (c->flags & CLIENT_REPEAT) { 1517 server_client_set_key_table(c, NULL); 1518 c->flags &= ~CLIENT_REPEAT; 1519 server_status_client(c); 1520 } 1521 } 1522 1523 /* Double-click callback. */ 1524 static void 1525 server_client_click_timer(__unused int fd, __unused short events, void *data) 1526 { 1527 struct client *c = data; 1528 1529 c->flags &= ~(CLIENT_DOUBLECLICK|CLIENT_TRIPLECLICK); 1530 } 1531 1532 /* Check if client should be exited. */ 1533 static void 1534 server_client_check_exit(struct client *c) 1535 { 1536 if (~c->flags & CLIENT_EXIT) 1537 return; 1538 if (c->flags & CLIENT_EXITED) 1539 return; 1540 1541 if (EVBUFFER_LENGTH(c->stdin_data) != 0) 1542 return; 1543 if (EVBUFFER_LENGTH(c->stdout_data) != 0) 1544 return; 1545 if (EVBUFFER_LENGTH(c->stderr_data) != 0) 1546 return; 1547 1548 if (c->flags & CLIENT_ATTACHED) 1549 notify_client("client-detached", c); 1550 proc_send(c->peer, MSG_EXIT, -1, &c->retval, sizeof c->retval); 1551 c->flags |= CLIENT_EXITED; 1552 } 1553 1554 /* Redraw timer callback. */ 1555 static void 1556 server_client_redraw_timer(__unused int fd, __unused short events, 1557 __unused void* data) 1558 { 1559 log_debug("redraw timer fired"); 1560 } 1561 1562 /* Check for client redraws. */ 1563 static void 1564 server_client_check_redraw(struct client *c) 1565 { 1566 struct session *s = c->session; 1567 struct tty *tty = &c->tty; 1568 struct window_pane *wp; 1569 int needed, flags; 1570 struct timeval tv = { .tv_usec = 1000 }; 1571 static struct event ev; 1572 size_t left; 1573 1574 if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED)) 1575 return; 1576 if (c->flags & CLIENT_ALLREDRAWFLAGS) { 1577 log_debug("%s: redraw%s%s%s%s", c->name, 1578 (c->flags & CLIENT_REDRAWWINDOW) ? " window" : "", 1579 (c->flags & CLIENT_REDRAWSTATUS) ? " status" : "", 1580 (c->flags & CLIENT_REDRAWBORDERS) ? " borders" : "", 1581 (c->flags & CLIENT_REDRAWOVERLAY) ? " overlay" : ""); 1582 } 1583 1584 /* 1585 * If there is outstanding data, defer the redraw until it has been 1586 * consumed. We can just add a timer to get out of the event loop and 1587 * end up back here. 1588 */ 1589 needed = 0; 1590 if (c->flags & CLIENT_ALLREDRAWFLAGS) 1591 needed = 1; 1592 else { 1593 TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) { 1594 if (wp->flags & PANE_REDRAW) { 1595 needed = 1; 1596 break; 1597 } 1598 } 1599 } 1600 if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) { 1601 log_debug("%s: redraw deferred (%zu left)", c->name, left); 1602 if (!evtimer_initialized(&ev)) 1603 evtimer_set(&ev, server_client_redraw_timer, NULL); 1604 if (!evtimer_pending(&ev, NULL)) { 1605 log_debug("redraw timer started"); 1606 evtimer_add(&ev, &tv); 1607 } 1608 1609 /* 1610 * We may have got here for a single pane redraw, but force a 1611 * full redraw next time in case other panes have been updated. 1612 */ 1613 c->flags |= CLIENT_ALLREDRAWFLAGS; 1614 return; 1615 } else if (needed) 1616 log_debug("%s: redraw needed", c->name); 1617 1618 flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR); 1619 tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE)) | TTY_NOCURSOR; 1620 1621 if (~c->flags & CLIENT_REDRAWWINDOW) { 1622 /* 1623 * If not redrawing the entire window, check whether each pane 1624 * needs to be redrawn. 1625 */ 1626 TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) { 1627 if (wp->flags & PANE_REDRAW) { 1628 tty_update_mode(tty, tty->mode, NULL); 1629 screen_redraw_pane(c, wp); 1630 } 1631 } 1632 } 1633 1634 if (c->flags & CLIENT_ALLREDRAWFLAGS) { 1635 if (options_get_number(s->options, "set-titles")) 1636 server_client_set_title(c); 1637 screen_redraw_screen(c); 1638 } 1639 1640 tty->flags = (tty->flags & ~(TTY_FREEZE|TTY_NOCURSOR)) | flags; 1641 tty_update_mode(tty, tty->mode, NULL); 1642 1643 c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE); 1644 1645 if (needed) { 1646 /* 1647 * We would have deferred the redraw unless the output buffer 1648 * was empty, so we can record how many bytes the redraw 1649 * generated. 1650 */ 1651 c->redraw = EVBUFFER_LENGTH(tty->out); 1652 log_debug("%s: redraw added %zu bytes", c->name, c->redraw); 1653 } 1654 } 1655 1656 /* Set client title. */ 1657 static void 1658 server_client_set_title(struct client *c) 1659 { 1660 struct session *s = c->session; 1661 const char *template; 1662 char *title; 1663 struct format_tree *ft; 1664 1665 template = options_get_string(s->options, "set-titles-string"); 1666 1667 ft = format_create(c, NULL, FORMAT_NONE, 0); 1668 format_defaults(ft, c, NULL, NULL, NULL); 1669 1670 title = format_expand_time(ft, template); 1671 if (c->title == NULL || strcmp(title, c->title) != 0) { 1672 free(c->title); 1673 c->title = xstrdup(title); 1674 tty_set_title(&c->tty, c->title); 1675 } 1676 free(title); 1677 1678 format_free(ft); 1679 } 1680 1681 /* Dispatch message from client. */ 1682 static void 1683 server_client_dispatch(struct imsg *imsg, void *arg) 1684 { 1685 struct client *c = arg; 1686 struct msg_stdin_data stdindata; 1687 const char *data; 1688 ssize_t datalen; 1689 struct session *s; 1690 1691 if (c->flags & CLIENT_DEAD) 1692 return; 1693 1694 if (imsg == NULL) { 1695 server_client_lost(c); 1696 return; 1697 } 1698 1699 data = imsg->data; 1700 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 1701 1702 switch (imsg->hdr.type) { 1703 case MSG_IDENTIFY_FLAGS: 1704 case MSG_IDENTIFY_TERM: 1705 case MSG_IDENTIFY_TTYNAME: 1706 case MSG_IDENTIFY_CWD: 1707 case MSG_IDENTIFY_STDIN: 1708 case MSG_IDENTIFY_ENVIRON: 1709 case MSG_IDENTIFY_CLIENTPID: 1710 case MSG_IDENTIFY_DONE: 1711 server_client_dispatch_identify(c, imsg); 1712 break; 1713 case MSG_COMMAND: 1714 server_client_dispatch_command(c, imsg); 1715 break; 1716 case MSG_STDIN: 1717 if (datalen != sizeof stdindata) 1718 fatalx("bad MSG_STDIN size"); 1719 memcpy(&stdindata, data, sizeof stdindata); 1720 1721 if (c->stdin_callback == NULL) 1722 break; 1723 if (stdindata.size <= 0) 1724 c->stdin_closed = 1; 1725 else { 1726 evbuffer_add(c->stdin_data, stdindata.data, 1727 stdindata.size); 1728 } 1729 c->stdin_callback(c, c->stdin_closed, c->stdin_callback_data); 1730 break; 1731 case MSG_RESIZE: 1732 if (datalen != 0) 1733 fatalx("bad MSG_RESIZE size"); 1734 1735 if (c->flags & CLIENT_CONTROL) 1736 break; 1737 server_client_clear_overlay(c); 1738 tty_resize(&c->tty); 1739 recalculate_sizes(); 1740 server_redraw_client(c); 1741 if (c->session != NULL) 1742 notify_client("client-resized", c); 1743 break; 1744 case MSG_EXITING: 1745 if (datalen != 0) 1746 fatalx("bad MSG_EXITING size"); 1747 1748 c->session = NULL; 1749 tty_close(&c->tty); 1750 proc_send(c->peer, MSG_EXITED, -1, NULL, 0); 1751 break; 1752 case MSG_WAKEUP: 1753 case MSG_UNLOCK: 1754 if (datalen != 0) 1755 fatalx("bad MSG_WAKEUP size"); 1756 1757 if (!(c->flags & CLIENT_SUSPENDED)) 1758 break; 1759 c->flags &= ~CLIENT_SUSPENDED; 1760 1761 if (c->tty.fd == -1) /* exited in the meantime */ 1762 break; 1763 s = c->session; 1764 1765 if (gettimeofday(&c->activity_time, NULL) != 0) 1766 fatal("gettimeofday failed"); 1767 1768 tty_start_tty(&c->tty); 1769 server_redraw_client(c); 1770 recalculate_sizes(); 1771 1772 if (s != NULL) 1773 session_update_activity(s, &c->activity_time); 1774 break; 1775 case MSG_SHELL: 1776 if (datalen != 0) 1777 fatalx("bad MSG_SHELL size"); 1778 1779 server_client_dispatch_shell(c); 1780 break; 1781 } 1782 } 1783 1784 /* Callback when command is done. */ 1785 static enum cmd_retval 1786 server_client_command_done(struct cmdq_item *item, __unused void *data) 1787 { 1788 struct client *c = item->client; 1789 1790 if (~c->flags & CLIENT_ATTACHED) 1791 c->flags |= CLIENT_EXIT; 1792 return (CMD_RETURN_NORMAL); 1793 } 1794 1795 /* Handle command message. */ 1796 static void 1797 server_client_dispatch_command(struct client *c, struct imsg *imsg) 1798 { 1799 struct msg_command_data data; 1800 char *buf; 1801 size_t len; 1802 int argc; 1803 char **argv, *cause; 1804 struct cmd_parse_result *pr; 1805 1806 if (c->flags & CLIENT_EXIT) 1807 return; 1808 1809 if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data) 1810 fatalx("bad MSG_COMMAND size"); 1811 memcpy(&data, imsg->data, sizeof data); 1812 1813 buf = (char *)imsg->data + sizeof data; 1814 len = imsg->hdr.len - IMSG_HEADER_SIZE - sizeof data; 1815 if (len > 0 && buf[len - 1] != '\0') 1816 fatalx("bad MSG_COMMAND string"); 1817 1818 argc = data.argc; 1819 if (cmd_unpack_argv(buf, len, argc, &argv) != 0) { 1820 cause = xstrdup("command too long"); 1821 goto error; 1822 } 1823 1824 if (argc == 0) { 1825 argc = 1; 1826 argv = xcalloc(1, sizeof *argv); 1827 *argv = xstrdup("new-session"); 1828 } 1829 1830 pr = cmd_parse_from_arguments(argc, argv, NULL); 1831 switch (pr->status) { 1832 case CMD_PARSE_EMPTY: 1833 cause = xstrdup("empty command"); 1834 goto error; 1835 case CMD_PARSE_ERROR: 1836 cause = pr->error; 1837 goto error; 1838 case CMD_PARSE_SUCCESS: 1839 break; 1840 } 1841 cmd_free_argv(argc, argv); 1842 1843 cmdq_append(c, cmdq_get_command(pr->cmdlist, NULL, NULL, 0)); 1844 cmdq_append(c, cmdq_get_callback(server_client_command_done, NULL)); 1845 1846 cmd_list_free(pr->cmdlist); 1847 return; 1848 1849 error: 1850 cmd_free_argv(argc, argv); 1851 1852 cmdq_append(c, cmdq_get_error(cause)); 1853 free(cause); 1854 1855 c->flags |= CLIENT_EXIT; 1856 } 1857 1858 /* Handle identify message. */ 1859 static void 1860 server_client_dispatch_identify(struct client *c, struct imsg *imsg) 1861 { 1862 const char *data, *home; 1863 size_t datalen; 1864 int flags; 1865 char *name; 1866 1867 if (c->flags & CLIENT_IDENTIFIED) 1868 fatalx("out-of-order identify message"); 1869 1870 data = imsg->data; 1871 datalen = imsg->hdr.len - IMSG_HEADER_SIZE; 1872 1873 switch (imsg->hdr.type) { 1874 case MSG_IDENTIFY_FLAGS: 1875 if (datalen != sizeof flags) 1876 fatalx("bad MSG_IDENTIFY_FLAGS size"); 1877 memcpy(&flags, data, sizeof flags); 1878 c->flags |= flags; 1879 log_debug("client %p IDENTIFY_FLAGS %#x", c, flags); 1880 break; 1881 case MSG_IDENTIFY_TERM: 1882 if (datalen == 0 || data[datalen - 1] != '\0') 1883 fatalx("bad MSG_IDENTIFY_TERM string"); 1884 c->term = xstrdup(data); 1885 log_debug("client %p IDENTIFY_TERM %s", c, data); 1886 break; 1887 case MSG_IDENTIFY_TTYNAME: 1888 if (datalen == 0 || data[datalen - 1] != '\0') 1889 fatalx("bad MSG_IDENTIFY_TTYNAME string"); 1890 c->ttyname = xstrdup(data); 1891 log_debug("client %p IDENTIFY_TTYNAME %s", c, data); 1892 break; 1893 case MSG_IDENTIFY_CWD: 1894 if (datalen == 0 || data[datalen - 1] != '\0') 1895 fatalx("bad MSG_IDENTIFY_CWD string"); 1896 if (access(data, X_OK) == 0) 1897 c->cwd = xstrdup(data); 1898 else if ((home = find_home()) != NULL) 1899 c->cwd = xstrdup(home); 1900 else 1901 c->cwd = xstrdup("/"); 1902 log_debug("client %p IDENTIFY_CWD %s", c, data); 1903 break; 1904 case MSG_IDENTIFY_STDIN: 1905 if (datalen != 0) 1906 fatalx("bad MSG_IDENTIFY_STDIN size"); 1907 c->fd = imsg->fd; 1908 log_debug("client %p IDENTIFY_STDIN %d", c, imsg->fd); 1909 break; 1910 case MSG_IDENTIFY_ENVIRON: 1911 if (datalen == 0 || data[datalen - 1] != '\0') 1912 fatalx("bad MSG_IDENTIFY_ENVIRON string"); 1913 if (strchr(data, '=') != NULL) 1914 environ_put(c->environ, data); 1915 log_debug("client %p IDENTIFY_ENVIRON %s", c, data); 1916 break; 1917 case MSG_IDENTIFY_CLIENTPID: 1918 if (datalen != sizeof c->pid) 1919 fatalx("bad MSG_IDENTIFY_CLIENTPID size"); 1920 memcpy(&c->pid, data, sizeof c->pid); 1921 log_debug("client %p IDENTIFY_CLIENTPID %ld", c, (long)c->pid); 1922 break; 1923 default: 1924 break; 1925 } 1926 1927 if (imsg->hdr.type != MSG_IDENTIFY_DONE) 1928 return; 1929 c->flags |= CLIENT_IDENTIFIED; 1930 1931 if (*c->ttyname != '\0') 1932 name = xstrdup(c->ttyname); 1933 else 1934 xasprintf(&name, "client-%ld", (long)c->pid); 1935 c->name = name; 1936 log_debug("client %p name is %s", c, c->name); 1937 1938 #ifdef __CYGWIN__ 1939 c->fd = open(c->ttyname, O_RDWR|O_NOCTTY); 1940 #endif 1941 1942 if (c->flags & CLIENT_CONTROL) { 1943 c->stdin_callback = control_callback; 1944 1945 evbuffer_free(c->stderr_data); 1946 c->stderr_data = c->stdout_data; 1947 1948 if (c->flags & CLIENT_CONTROLCONTROL) 1949 evbuffer_add_printf(c->stdout_data, "\033P1000p"); 1950 proc_send(c->peer, MSG_STDIN, -1, NULL, 0); 1951 1952 c->tty.fd = -1; 1953 1954 close(c->fd); 1955 c->fd = -1; 1956 } else if (c->fd != -1) { 1957 if (tty_init(&c->tty, c, c->fd, c->term) != 0) { 1958 close(c->fd); 1959 c->fd = -1; 1960 } else { 1961 if (c->flags & CLIENT_UTF8) 1962 c->tty.flags |= TTY_UTF8; 1963 if (c->flags & CLIENT_256COLOURS) 1964 c->tty.term_flags |= TERM_256COLOURS; 1965 tty_resize(&c->tty); 1966 c->flags |= CLIENT_TERMINAL; 1967 } 1968 } 1969 1970 /* 1971 * If this is the first client that has finished identifying, load 1972 * configuration files. 1973 */ 1974 if ((~c->flags & CLIENT_EXIT) && 1975 !cfg_finished && 1976 c == TAILQ_FIRST(&clients) && 1977 TAILQ_NEXT(c, entry) == NULL) 1978 start_cfg(); 1979 } 1980 1981 /* Handle shell message. */ 1982 static void 1983 server_client_dispatch_shell(struct client *c) 1984 { 1985 const char *shell; 1986 1987 shell = options_get_string(global_s_options, "default-shell"); 1988 if (*shell == '\0' || areshell(shell)) 1989 shell = _PATH_BSHELL; 1990 proc_send(c->peer, MSG_SHELL, -1, shell, strlen(shell) + 1); 1991 1992 proc_kill_peer(c->peer); 1993 } 1994 1995 /* Event callback to push more stdout data if any left. */ 1996 static void 1997 server_client_stdout_cb(__unused int fd, __unused short events, void *arg) 1998 { 1999 struct client *c = arg; 2000 2001 if (~c->flags & CLIENT_DEAD) 2002 server_client_push_stdout(c); 2003 server_client_unref(c); 2004 } 2005 2006 /* Push stdout to client if possible. */ 2007 void 2008 server_client_push_stdout(struct client *c) 2009 { 2010 struct msg_stdout_data data; 2011 size_t sent, left; 2012 2013 left = EVBUFFER_LENGTH(c->stdout_data); 2014 while (left != 0) { 2015 sent = left; 2016 if (sent > sizeof data.data) 2017 sent = sizeof data.data; 2018 memcpy(data.data, EVBUFFER_DATA(c->stdout_data), sent); 2019 data.size = sent; 2020 2021 if (proc_send(c->peer, MSG_STDOUT, -1, &data, sizeof data) != 0) 2022 break; 2023 evbuffer_drain(c->stdout_data, sent); 2024 2025 left = EVBUFFER_LENGTH(c->stdout_data); 2026 log_debug("%s: client %p, sent %zu, left %zu", __func__, c, 2027 sent, left); 2028 } 2029 if (left != 0) { 2030 c->references++; 2031 event_once(-1, EV_TIMEOUT, server_client_stdout_cb, c, NULL); 2032 log_debug("%s: client %p, queued", __func__, c); 2033 } 2034 } 2035 2036 /* Event callback to push more stderr data if any left. */ 2037 static void 2038 server_client_stderr_cb(__unused int fd, __unused short events, void *arg) 2039 { 2040 struct client *c = arg; 2041 2042 if (~c->flags & CLIENT_DEAD) 2043 server_client_push_stderr(c); 2044 server_client_unref(c); 2045 } 2046 2047 /* Push stderr to client if possible. */ 2048 void 2049 server_client_push_stderr(struct client *c) 2050 { 2051 struct msg_stderr_data data; 2052 size_t sent, left; 2053 2054 if (c->stderr_data == c->stdout_data) { 2055 server_client_push_stdout(c); 2056 return; 2057 } 2058 2059 left = EVBUFFER_LENGTH(c->stderr_data); 2060 while (left != 0) { 2061 sent = left; 2062 if (sent > sizeof data.data) 2063 sent = sizeof data.data; 2064 memcpy(data.data, EVBUFFER_DATA(c->stderr_data), sent); 2065 data.size = sent; 2066 2067 if (proc_send(c->peer, MSG_STDERR, -1, &data, sizeof data) != 0) 2068 break; 2069 evbuffer_drain(c->stderr_data, sent); 2070 2071 left = EVBUFFER_LENGTH(c->stderr_data); 2072 log_debug("%s: client %p, sent %zu, left %zu", __func__, c, 2073 sent, left); 2074 } 2075 if (left != 0) { 2076 c->references++; 2077 event_once(-1, EV_TIMEOUT, server_client_stderr_cb, c, NULL); 2078 log_debug("%s: client %p, queued", __func__, c); 2079 } 2080 } 2081 2082 /* Add to client message log. */ 2083 void 2084 server_client_add_message(struct client *c, const char *fmt, ...) 2085 { 2086 struct message_entry *msg, *msg1; 2087 char *s; 2088 va_list ap; 2089 u_int limit; 2090 2091 va_start(ap, fmt); 2092 xvasprintf(&s, fmt, ap); 2093 va_end(ap); 2094 2095 log_debug("message %s (client %p)", s, c); 2096 2097 msg = xcalloc(1, sizeof *msg); 2098 msg->msg_time = time(NULL); 2099 msg->msg_num = c->message_next++; 2100 msg->msg = s; 2101 TAILQ_INSERT_TAIL(&c->message_log, msg, entry); 2102 2103 limit = options_get_number(global_options, "message-limit"); 2104 TAILQ_FOREACH_SAFE(msg, &c->message_log, entry, msg1) { 2105 if (msg->msg_num + limit >= c->message_next) 2106 break; 2107 free(msg->msg); 2108 TAILQ_REMOVE(&c->message_log, msg, entry); 2109 free(msg); 2110 } 2111 } 2112 2113 /* Get client working directory. */ 2114 const char * 2115 server_client_get_cwd(struct client *c, struct session *s) 2116 { 2117 const char *home; 2118 2119 if (!cfg_finished && cfg_client != NULL) 2120 return (cfg_client->cwd); 2121 if (c != NULL && c->session == NULL && c->cwd != NULL) 2122 return (c->cwd); 2123 if (s != NULL && s->cwd != NULL) 2124 return (s->cwd); 2125 if (c != NULL && (s = c->session) != NULL && s->cwd != NULL) 2126 return (s->cwd); 2127 if ((home = find_home()) != NULL) 2128 return (home); 2129 return ("/"); 2130 } 2131 2132 /* Resolve an absolute path or relative to client working directory. */ 2133 char * 2134 server_client_get_path(struct client *c, const char *file) 2135 { 2136 char *path, resolved[PATH_MAX]; 2137 2138 if (*file == '/') 2139 path = xstrdup(file); 2140 else 2141 xasprintf(&path, "%s/%s", server_client_get_cwd(c, NULL), file); 2142 if (realpath(path, resolved) == NULL) 2143 return (path); 2144 free(path); 2145 return (xstrdup(resolved)); 2146 } 2147