1 /* $OpenBSD: cmd-queue.c,v 1.107 2021/08/21 17:25:32 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2013 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 21 #include <ctype.h> 22 #include <stdlib.h> 23 #include <string.h> 24 #include <time.h> 25 26 #include "tmux.h" 27 28 /* Command queue flags. */ 29 #define CMDQ_FIRED 0x1 30 #define CMDQ_WAITING 0x2 31 32 /* Command queue item type. */ 33 enum cmdq_type { 34 CMDQ_COMMAND, 35 CMDQ_CALLBACK, 36 }; 37 38 /* Command queue item. */ 39 struct cmdq_item { 40 char *name; 41 struct cmdq_list *queue; 42 struct cmdq_item *next; 43 44 struct client *client; 45 struct client *target_client; 46 47 enum cmdq_type type; 48 u_int group; 49 50 u_int number; 51 time_t time; 52 53 int flags; 54 55 struct cmdq_state *state; 56 struct cmd_find_state source; 57 struct cmd_find_state target; 58 59 struct cmd_list *cmdlist; 60 struct cmd *cmd; 61 62 cmdq_cb cb; 63 void *data; 64 65 TAILQ_ENTRY(cmdq_item) entry; 66 }; 67 TAILQ_HEAD(cmdq_item_list, cmdq_item); 68 69 /* 70 * Command queue state. This is the context for commands on the command queue. 71 * It holds information about how the commands were fired (the key and flags), 72 * any additional formats for the commands, and the current default target. 73 * Multiple commands can share the same state and a command may update the 74 * default target. 75 */ 76 struct cmdq_state { 77 int references; 78 int flags; 79 80 struct format_tree *formats; 81 82 struct key_event event; 83 struct cmd_find_state current; 84 }; 85 86 /* Command queue. */ 87 struct cmdq_list { 88 struct cmdq_item *item; 89 struct cmdq_item_list list; 90 }; 91 92 /* Get command queue name. */ 93 static const char * 94 cmdq_name(struct client *c) 95 { 96 static char s[256]; 97 98 if (c == NULL) 99 return ("<global>"); 100 if (c->name != NULL) 101 xsnprintf(s, sizeof s, "<%s>", c->name); 102 else 103 xsnprintf(s, sizeof s, "<%p>", c); 104 return (s); 105 } 106 107 /* Get command queue from client. */ 108 static struct cmdq_list * 109 cmdq_get(struct client *c) 110 { 111 static struct cmdq_list *global_queue; 112 113 if (c == NULL) { 114 if (global_queue == NULL) 115 global_queue = cmdq_new(); 116 return (global_queue); 117 } 118 return (c->queue); 119 } 120 121 /* Create a queue. */ 122 struct cmdq_list * 123 cmdq_new(void) 124 { 125 struct cmdq_list *queue; 126 127 queue = xcalloc (1, sizeof *queue); 128 TAILQ_INIT (&queue->list); 129 return (queue); 130 } 131 132 /* Free a queue. */ 133 void 134 cmdq_free(struct cmdq_list *queue) 135 { 136 if (!TAILQ_EMPTY(&queue->list)) 137 fatalx("queue not empty"); 138 free(queue); 139 } 140 141 /* Get item name. */ 142 const char * 143 cmdq_get_name(struct cmdq_item *item) 144 { 145 return (item->name); 146 } 147 148 /* Get item client. */ 149 struct client * 150 cmdq_get_client(struct cmdq_item *item) 151 { 152 return (item->client); 153 } 154 155 /* Get item target client. */ 156 struct client * 157 cmdq_get_target_client(struct cmdq_item *item) 158 { 159 return (item->target_client); 160 } 161 162 /* Get item state. */ 163 struct cmdq_state * 164 cmdq_get_state(struct cmdq_item *item) 165 { 166 return (item->state); 167 } 168 169 /* Get item target. */ 170 struct cmd_find_state * 171 cmdq_get_target(struct cmdq_item *item) 172 { 173 return (&item->target); 174 } 175 176 /* Get item source. */ 177 struct cmd_find_state * 178 cmdq_get_source(struct cmdq_item *item) 179 { 180 return (&item->source); 181 } 182 183 /* Get state event. */ 184 struct key_event * 185 cmdq_get_event(struct cmdq_item *item) 186 { 187 return (&item->state->event); 188 } 189 190 /* Get state current target. */ 191 struct cmd_find_state * 192 cmdq_get_current(struct cmdq_item *item) 193 { 194 return (&item->state->current); 195 } 196 197 /* Get state flags. */ 198 int 199 cmdq_get_flags(struct cmdq_item *item) 200 { 201 return (item->state->flags); 202 } 203 204 /* Create a new state. */ 205 struct cmdq_state * 206 cmdq_new_state(struct cmd_find_state *current, struct key_event *event, 207 int flags) 208 { 209 struct cmdq_state *state; 210 211 state = xcalloc(1, sizeof *state); 212 state->references = 1; 213 state->flags = flags; 214 215 if (event != NULL) 216 memcpy(&state->event, event, sizeof state->event); 217 else 218 state->event.key = KEYC_NONE; 219 if (current != NULL && cmd_find_valid_state(current)) 220 cmd_find_copy_state(&state->current, current); 221 else 222 cmd_find_clear_state(&state->current, 0); 223 224 return (state); 225 } 226 227 /* Add a reference to a state. */ 228 struct cmdq_state * 229 cmdq_link_state(struct cmdq_state *state) 230 { 231 state->references++; 232 return (state); 233 } 234 235 /* Make a copy of a state. */ 236 struct cmdq_state * 237 cmdq_copy_state(struct cmdq_state *state) 238 { 239 return (cmdq_new_state(&state->current, &state->event, state->flags)); 240 } 241 242 /* Free a state. */ 243 void 244 cmdq_free_state(struct cmdq_state *state) 245 { 246 if (--state->references != 0) 247 return; 248 249 if (state->formats != NULL) 250 format_free(state->formats); 251 free(state); 252 } 253 254 /* Add a format to command queue. */ 255 void 256 cmdq_add_format(struct cmdq_state *state, const char *key, const char *fmt, ...) 257 { 258 va_list ap; 259 char *value; 260 261 va_start(ap, fmt); 262 xvasprintf(&value, fmt, ap); 263 va_end(ap); 264 265 if (state->formats == NULL) 266 state->formats = format_create(NULL, NULL, FORMAT_NONE, 0); 267 format_add(state->formats, key, "%s", value); 268 269 free(value); 270 } 271 272 /* Add formats to command queue. */ 273 void 274 cmdq_add_formats(struct cmdq_state *state, struct format_tree *ft) 275 { 276 if (state->formats == NULL) 277 state->formats = format_create(NULL, NULL, FORMAT_NONE, 0); 278 format_merge(state->formats, ft); 279 } 280 281 /* Merge formats from item. */ 282 void 283 cmdq_merge_formats(struct cmdq_item *item, struct format_tree *ft) 284 { 285 const struct cmd_entry *entry; 286 287 if (item->cmd != NULL) { 288 entry = cmd_get_entry(item->cmd); 289 format_add(ft, "command", "%s", entry->name); 290 } 291 if (item->state->formats != NULL) 292 format_merge(ft, item->state->formats); 293 } 294 295 /* Append an item. */ 296 struct cmdq_item * 297 cmdq_append(struct client *c, struct cmdq_item *item) 298 { 299 struct cmdq_list *queue = cmdq_get(c); 300 struct cmdq_item *next; 301 302 do { 303 next = item->next; 304 item->next = NULL; 305 306 if (c != NULL) 307 c->references++; 308 item->client = c; 309 310 item->queue = queue; 311 TAILQ_INSERT_TAIL(&queue->list, item, entry); 312 log_debug("%s %s: %s", __func__, cmdq_name(c), item->name); 313 314 item = next; 315 } while (item != NULL); 316 return (TAILQ_LAST(&queue->list, cmdq_item_list)); 317 } 318 319 /* Insert an item. */ 320 struct cmdq_item * 321 cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item) 322 { 323 struct client *c = after->client; 324 struct cmdq_list *queue = after->queue; 325 struct cmdq_item *next; 326 327 do { 328 next = item->next; 329 item->next = after->next; 330 after->next = item; 331 332 if (c != NULL) 333 c->references++; 334 item->client = c; 335 336 item->queue = queue; 337 TAILQ_INSERT_AFTER(&queue->list, after, item, entry); 338 log_debug("%s %s: %s after %s", __func__, cmdq_name(c), 339 item->name, after->name); 340 341 after = item; 342 item = next; 343 } while (item != NULL); 344 return (after); 345 } 346 347 /* Insert a hook. */ 348 void 349 cmdq_insert_hook(struct session *s, struct cmdq_item *item, 350 struct cmd_find_state *current, const char *fmt, ...) 351 { 352 struct cmdq_state *state = item->state; 353 struct cmd *cmd = item->cmd; 354 struct args *args = cmd_get_args(cmd); 355 struct args_entry *ae; 356 struct args_value *av; 357 struct options *oo; 358 va_list ap; 359 char *name, tmp[32], flag, *arguments; 360 u_int i; 361 const char *value; 362 struct cmdq_item *new_item; 363 struct cmdq_state *new_state; 364 struct options_entry *o; 365 struct options_array_item *a; 366 struct cmd_list *cmdlist; 367 368 if (item->state->flags & CMDQ_STATE_NOHOOKS) 369 return; 370 if (s == NULL) 371 oo = global_s_options; 372 else 373 oo = s->options; 374 375 va_start(ap, fmt); 376 xvasprintf(&name, fmt, ap); 377 va_end(ap); 378 379 o = options_get(oo, name); 380 if (o == NULL) { 381 free(name); 382 return; 383 } 384 log_debug("running hook %s (parent %p)", name, item); 385 386 /* 387 * The hooks get a new state because they should not update the current 388 * target or formats for any subsequent commands. 389 */ 390 new_state = cmdq_new_state(current, &state->event, CMDQ_STATE_NOHOOKS); 391 cmdq_add_format(new_state, "hook", "%s", name); 392 393 arguments = args_print(args); 394 cmdq_add_format(new_state, "hook_arguments", "%s", arguments); 395 free(arguments); 396 397 for (i = 0; i < args_count(args); i++) { 398 xsnprintf(tmp, sizeof tmp, "hook_argument_%d", i); 399 cmdq_add_format(new_state, tmp, "%s", args_string(args, i)); 400 } 401 flag = args_first(args, &ae); 402 while (flag != 0) { 403 value = args_get(args, flag); 404 if (value == NULL) { 405 xsnprintf(tmp, sizeof tmp, "hook_flag_%c", flag); 406 cmdq_add_format(new_state, tmp, "1"); 407 } else { 408 xsnprintf(tmp, sizeof tmp, "hook_flag_%c", flag); 409 cmdq_add_format(new_state, tmp, "%s", value); 410 } 411 412 i = 0; 413 av = args_first_value(args, flag); 414 while (av != NULL) { 415 xsnprintf(tmp, sizeof tmp, "hook_flag_%c_%d", flag, i); 416 cmdq_add_format(new_state, tmp, "%s", av->string); 417 i++; 418 av = args_next_value(av); 419 } 420 421 flag = args_next(&ae); 422 } 423 424 a = options_array_first(o); 425 while (a != NULL) { 426 cmdlist = options_array_item_value(a)->cmdlist; 427 if (cmdlist != NULL) { 428 new_item = cmdq_get_command(cmdlist, new_state); 429 if (item != NULL) 430 item = cmdq_insert_after(item, new_item); 431 else 432 item = cmdq_append(NULL, new_item); 433 } 434 a = options_array_next(a); 435 } 436 437 cmdq_free_state(new_state); 438 free(name); 439 } 440 441 /* Continue processing command queue. */ 442 void 443 cmdq_continue(struct cmdq_item *item) 444 { 445 item->flags &= ~CMDQ_WAITING; 446 } 447 448 /* Remove an item. */ 449 static void 450 cmdq_remove(struct cmdq_item *item) 451 { 452 if (item->client != NULL) 453 server_client_unref(item->client); 454 if (item->cmdlist != NULL) 455 cmd_list_free(item->cmdlist); 456 cmdq_free_state(item->state); 457 458 TAILQ_REMOVE(&item->queue->list, item, entry); 459 460 free(item->name); 461 free(item); 462 } 463 464 /* Remove all subsequent items that match this item's group. */ 465 static void 466 cmdq_remove_group(struct cmdq_item *item) 467 { 468 struct cmdq_item *this, *next; 469 470 if (item->group == 0) 471 return; 472 this = TAILQ_NEXT(item, entry); 473 while (this != NULL) { 474 next = TAILQ_NEXT(this, entry); 475 if (this->group == item->group) 476 cmdq_remove(this); 477 this = next; 478 } 479 } 480 481 /* Empty command callback. */ 482 static enum cmd_retval 483 cmdq_empty_command(__unused struct cmdq_item *item, __unused void *data) 484 { 485 return (CMD_RETURN_NORMAL); 486 } 487 488 /* Get a command for the command queue. */ 489 struct cmdq_item * 490 cmdq_get_command(struct cmd_list *cmdlist, struct cmdq_state *state) 491 { 492 struct cmdq_item *item, *first = NULL, *last = NULL; 493 struct cmd *cmd; 494 const struct cmd_entry *entry; 495 int created = 0; 496 497 if ((cmd = cmd_list_first(cmdlist)) == NULL) 498 return (cmdq_get_callback(cmdq_empty_command, NULL)); 499 500 if (state == NULL) { 501 state = cmdq_new_state(NULL, NULL, 0); 502 created = 1; 503 } 504 505 while (cmd != NULL) { 506 entry = cmd_get_entry(cmd); 507 508 item = xcalloc(1, sizeof *item); 509 xasprintf(&item->name, "[%s/%p]", entry->name, item); 510 item->type = CMDQ_COMMAND; 511 512 item->group = cmd_get_group(cmd); 513 item->state = cmdq_link_state(state); 514 515 item->cmdlist = cmdlist; 516 item->cmd = cmd; 517 518 cmdlist->references++; 519 log_debug("%s: %s group %u", __func__, item->name, item->group); 520 521 if (first == NULL) 522 first = item; 523 if (last != NULL) 524 last->next = item; 525 last = item; 526 527 cmd = cmd_list_next(cmd); 528 } 529 530 if (created) 531 cmdq_free_state(state); 532 return (first); 533 } 534 535 /* Fill in flag for a command. */ 536 static enum cmd_retval 537 cmdq_find_flag(struct cmdq_item *item, struct cmd_find_state *fs, 538 const struct cmd_entry_flag *flag) 539 { 540 const char *value; 541 542 if (flag->flag == 0) { 543 cmd_find_from_client(fs, item->target_client, 0); 544 return (CMD_RETURN_NORMAL); 545 } 546 547 value = args_get(cmd_get_args(item->cmd), flag->flag); 548 if (cmd_find_target(fs, item, value, flag->type, flag->flags) != 0) { 549 cmd_find_clear_state(fs, 0); 550 return (CMD_RETURN_ERROR); 551 } 552 return (CMD_RETURN_NORMAL); 553 } 554 555 /* Add message with command. */ 556 static void 557 cmdq_add_message(struct cmdq_item *item) 558 { 559 struct client *c = item->client; 560 struct cmdq_state *state = item->state; 561 const char *name, *key; 562 char *tmp; 563 564 tmp = cmd_print(item->cmd); 565 if (c != NULL) { 566 name = c->name; 567 if (c->session != NULL && state->event.key != KEYC_NONE) { 568 key = key_string_lookup_key(state->event.key, 0); 569 server_add_message("%s key %s: %s", name, key, tmp); 570 } else 571 server_add_message("%s command: %s", name, tmp); 572 } else 573 server_add_message("command: %s", tmp); 574 free(tmp); 575 } 576 577 /* Fire command on command queue. */ 578 static enum cmd_retval 579 cmdq_fire_command(struct cmdq_item *item) 580 { 581 const char *name = cmdq_name(item->client); 582 struct cmdq_state *state = item->state; 583 struct cmd *cmd = item->cmd; 584 struct args *args = cmd_get_args(cmd); 585 const struct cmd_entry *entry = cmd_get_entry(cmd); 586 struct client *tc, *saved = item->client; 587 enum cmd_retval retval; 588 struct cmd_find_state *fsp, fs; 589 int flags, quiet = 0; 590 char *tmp; 591 592 if (cfg_finished) 593 cmdq_add_message(item); 594 if (log_get_level() > 1) { 595 tmp = cmd_print(cmd); 596 log_debug("%s %s: (%u) %s", __func__, name, item->group, tmp); 597 free(tmp); 598 } 599 600 flags = !!(state->flags & CMDQ_STATE_CONTROL); 601 cmdq_guard(item, "begin", flags); 602 603 if (item->client == NULL) 604 item->client = cmd_find_client(item, NULL, 1); 605 606 if (entry->flags & CMD_CLIENT_CANFAIL) 607 quiet = 1; 608 if (entry->flags & CMD_CLIENT_CFLAG) { 609 tc = cmd_find_client(item, args_get(args, 'c'), quiet); 610 if (tc == NULL && !quiet) { 611 retval = CMD_RETURN_ERROR; 612 goto out; 613 } 614 } else if (entry->flags & CMD_CLIENT_TFLAG) { 615 tc = cmd_find_client(item, args_get(args, 't'), quiet); 616 if (tc == NULL && !quiet) { 617 retval = CMD_RETURN_ERROR; 618 goto out; 619 } 620 } else 621 tc = cmd_find_client(item, NULL, 1); 622 item->target_client = tc; 623 624 retval = cmdq_find_flag(item, &item->source, &entry->source); 625 if (retval == CMD_RETURN_ERROR) 626 goto out; 627 retval = cmdq_find_flag(item, &item->target, &entry->target); 628 if (retval == CMD_RETURN_ERROR) 629 goto out; 630 631 retval = entry->exec(cmd, item); 632 if (retval == CMD_RETURN_ERROR) 633 goto out; 634 635 if (entry->flags & CMD_AFTERHOOK) { 636 if (cmd_find_valid_state(&item->target)) 637 fsp = &item->target; 638 else if (cmd_find_valid_state(&item->state->current)) 639 fsp = &item->state->current; 640 else if (cmd_find_from_client(&fs, item->client, 0) == 0) 641 fsp = &fs; 642 else 643 goto out; 644 cmdq_insert_hook(fsp->s, item, fsp, "after-%s", entry->name); 645 } 646 647 out: 648 item->client = saved; 649 if (retval == CMD_RETURN_ERROR) 650 cmdq_guard(item, "error", flags); 651 else 652 cmdq_guard(item, "end", flags); 653 return (retval); 654 } 655 656 /* Get a callback for the command queue. */ 657 struct cmdq_item * 658 cmdq_get_callback1(const char *name, cmdq_cb cb, void *data) 659 { 660 struct cmdq_item *item; 661 662 item = xcalloc(1, sizeof *item); 663 xasprintf(&item->name, "[%s/%p]", name, item); 664 item->type = CMDQ_CALLBACK; 665 666 item->group = 0; 667 item->state = cmdq_new_state(NULL, NULL, 0); 668 669 item->cb = cb; 670 item->data = data; 671 672 return (item); 673 } 674 675 /* Generic error callback. */ 676 static enum cmd_retval 677 cmdq_error_callback(struct cmdq_item *item, void *data) 678 { 679 char *error = data; 680 681 cmdq_error(item, "%s", error); 682 free(error); 683 684 return (CMD_RETURN_NORMAL); 685 } 686 687 /* Get an error callback for the command queue. */ 688 struct cmdq_item * 689 cmdq_get_error(const char *error) 690 { 691 return (cmdq_get_callback(cmdq_error_callback, xstrdup(error))); 692 } 693 694 /* Fire callback on callback queue. */ 695 static enum cmd_retval 696 cmdq_fire_callback(struct cmdq_item *item) 697 { 698 return (item->cb(item, item->data)); 699 } 700 701 /* Process next item on command queue. */ 702 u_int 703 cmdq_next(struct client *c) 704 { 705 struct cmdq_list *queue = cmdq_get(c); 706 const char *name = cmdq_name(c); 707 struct cmdq_item *item; 708 enum cmd_retval retval; 709 u_int items = 0; 710 static u_int number; 711 712 if (TAILQ_EMPTY(&queue->list)) { 713 log_debug("%s %s: empty", __func__, name); 714 return (0); 715 } 716 if (TAILQ_FIRST(&queue->list)->flags & CMDQ_WAITING) { 717 log_debug("%s %s: waiting", __func__, name); 718 return (0); 719 } 720 721 log_debug("%s %s: enter", __func__, name); 722 for (;;) { 723 item = queue->item = TAILQ_FIRST(&queue->list); 724 if (item == NULL) 725 break; 726 log_debug("%s %s: %s (%d), flags %x", __func__, name, 727 item->name, item->type, item->flags); 728 729 /* 730 * Any item with the waiting flag set waits until an external 731 * event clears the flag (for example, a job - look at 732 * run-shell). 733 */ 734 if (item->flags & CMDQ_WAITING) 735 goto waiting; 736 737 /* 738 * Items are only fired once, once the fired flag is set, a 739 * waiting flag can only be cleared by an external event. 740 */ 741 if (~item->flags & CMDQ_FIRED) { 742 item->time = time(NULL); 743 item->number = ++number; 744 745 switch (item->type) { 746 case CMDQ_COMMAND: 747 retval = cmdq_fire_command(item); 748 749 /* 750 * If a command returns an error, remove any 751 * subsequent commands in the same group. 752 */ 753 if (retval == CMD_RETURN_ERROR) 754 cmdq_remove_group(item); 755 break; 756 case CMDQ_CALLBACK: 757 retval = cmdq_fire_callback(item); 758 break; 759 default: 760 retval = CMD_RETURN_ERROR; 761 break; 762 } 763 item->flags |= CMDQ_FIRED; 764 765 if (retval == CMD_RETURN_WAIT) { 766 item->flags |= CMDQ_WAITING; 767 goto waiting; 768 } 769 items++; 770 } 771 cmdq_remove(item); 772 } 773 queue->item = NULL; 774 775 log_debug("%s %s: exit (empty)", __func__, name); 776 return (items); 777 778 waiting: 779 log_debug("%s %s: exit (wait)", __func__, name); 780 return (items); 781 } 782 783 /* Get running item if any. */ 784 struct cmdq_item * 785 cmdq_running(struct client *c) 786 { 787 struct cmdq_list *queue = cmdq_get(c); 788 789 if (queue->item == NULL) 790 return (NULL); 791 if (queue->item->flags & CMDQ_WAITING) 792 return (NULL); 793 return (queue->item); 794 } 795 796 /* Print a guard line. */ 797 void 798 cmdq_guard(struct cmdq_item *item, const char *guard, int flags) 799 { 800 struct client *c = item->client; 801 long t = item->time; 802 u_int number = item->number; 803 804 if (c != NULL && (c->flags & CLIENT_CONTROL)) 805 control_write(c, "%%%s %ld %u %d", guard, t, number, flags); 806 } 807 808 /* Show message from command. */ 809 void 810 cmdq_print(struct cmdq_item *item, const char *fmt, ...) 811 { 812 struct client *c = item->client; 813 struct window_pane *wp; 814 struct window_mode_entry *wme; 815 va_list ap; 816 char *tmp, *msg; 817 818 va_start(ap, fmt); 819 xvasprintf(&msg, fmt, ap); 820 va_end(ap); 821 822 log_debug("%s: %s", __func__, msg); 823 824 if (c == NULL) 825 /* nothing */; 826 else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) { 827 if (~c->flags & CLIENT_UTF8) { 828 tmp = msg; 829 msg = utf8_sanitize(tmp); 830 free(tmp); 831 } 832 if (c->flags & CLIENT_CONTROL) 833 control_write(c, "%s", msg); 834 else 835 file_print(c, "%s\n", msg); 836 } else { 837 wp = server_client_get_pane(c); 838 wme = TAILQ_FIRST(&wp->modes); 839 if (wme == NULL || wme->mode != &window_view_mode) { 840 window_pane_set_mode(wp, NULL, &window_view_mode, NULL, 841 NULL); 842 } 843 window_copy_add(wp, "%s", msg); 844 } 845 846 free(msg); 847 } 848 849 /* Show error from command. */ 850 void 851 cmdq_error(struct cmdq_item *item, const char *fmt, ...) 852 { 853 struct client *c = item->client; 854 struct cmd *cmd = item->cmd; 855 va_list ap; 856 char *msg, *tmp; 857 const char *file; 858 u_int line; 859 860 va_start(ap, fmt); 861 xvasprintf(&msg, fmt, ap); 862 va_end(ap); 863 864 log_debug("%s: %s", __func__, msg); 865 866 if (c == NULL) { 867 cmd_get_source(cmd, &file, &line); 868 cfg_add_cause("%s:%u: %s", file, line, msg); 869 } else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) { 870 server_add_message("%s message: %s", c->name, msg); 871 if (~c->flags & CLIENT_UTF8) { 872 tmp = msg; 873 msg = utf8_sanitize(tmp); 874 free(tmp); 875 } 876 if (c->flags & CLIENT_CONTROL) 877 control_write(c, "%s", msg); 878 else 879 file_error(c, "%s\n", msg); 880 c->retval = 1; 881 } else { 882 *msg = toupper((u_char) *msg); 883 status_message_set(c, -1, 1, 0, "%s", msg); 884 } 885 886 free(msg); 887 } 888