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