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