xref: /openbsd-src/usr.bin/tmux/server-client.c (revision 5b859c19fe53bbea08f5c342e0a4470e99f883e1)
1 /* $OpenBSD: server-client.c,v 1.126 2014/10/22 23:18:53 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
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 
22 #include <errno.h>
23 #include <event.h>
24 #include <fcntl.h>
25 #include <paths.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <unistd.h>
30 
31 #include "tmux.h"
32 
33 void	server_client_check_focus(struct window_pane *);
34 void	server_client_check_resize(struct window_pane *);
35 void	server_client_check_mouse(struct client *, struct window_pane *);
36 void	server_client_repeat_timer(int, short, void *);
37 void	server_client_check_exit(struct client *);
38 void	server_client_check_redraw(struct client *);
39 void	server_client_set_title(struct client *);
40 void	server_client_reset_state(struct client *);
41 int	server_client_assume_paste(struct session *);
42 
43 int	server_client_msg_dispatch(struct client *);
44 void	server_client_msg_command(struct client *, struct imsg *);
45 void	server_client_msg_identify(struct client *, struct imsg *);
46 void	server_client_msg_shell(struct client *);
47 
48 /* Create a new client. */
49 void
50 server_client_create(int fd)
51 {
52 	struct client	*c;
53 	u_int		 i;
54 
55 	setblocking(fd, 0);
56 
57 	c = xcalloc(1, sizeof *c);
58 	c->references = 0;
59 	imsg_init(&c->ibuf, fd);
60 	server_update_event(c);
61 
62 	if (gettimeofday(&c->creation_time, NULL) != 0)
63 		fatal("gettimeofday failed");
64 	memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time);
65 
66 	environ_init(&c->environ);
67 
68 	c->cmdq = cmdq_new(c);
69 	c->cmdq->client_exit = 1;
70 
71 	c->stdin_data = evbuffer_new();
72 	c->stdout_data = evbuffer_new();
73 	c->stderr_data = evbuffer_new();
74 
75 	c->tty.fd = -1;
76 	c->title = NULL;
77 
78 	c->session = NULL;
79 	c->last_session = NULL;
80 	c->tty.sx = 80;
81 	c->tty.sy = 24;
82 
83 	screen_init(&c->status, c->tty.sx, 1, 0);
84 	RB_INIT(&c->status_new);
85 	RB_INIT(&c->status_old);
86 
87 	c->message_string = NULL;
88 	ARRAY_INIT(&c->message_log);
89 
90 	c->prompt_string = NULL;
91 	c->prompt_buffer = NULL;
92 	c->prompt_index = 0;
93 
94 	c->tty.mouse.xb = c->tty.mouse.button = 3;
95 	c->tty.mouse.x = c->tty.mouse.y = -1;
96 	c->tty.mouse.lx = c->tty.mouse.ly = -1;
97 	c->tty.mouse.sx = c->tty.mouse.sy = -1;
98 	c->tty.mouse.event = MOUSE_EVENT_UP;
99 	c->tty.mouse.flags = 0;
100 
101 	c->flags |= CLIENT_FOCUSED;
102 
103 	evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
104 
105 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
106 		if (ARRAY_ITEM(&clients, i) == NULL) {
107 			ARRAY_SET(&clients, i, c);
108 			return;
109 		}
110 	}
111 	ARRAY_ADD(&clients, c);
112 	log_debug("new client %d", fd);
113 }
114 
115 /* Open client terminal if needed. */
116 int
117 server_client_open(struct client *c, char **cause)
118 {
119 	if (c->flags & CLIENT_CONTROL)
120 		return (0);
121 
122 	if (strcmp(c->ttyname, "/dev/tty") == 0) {
123 		*cause = xstrdup("can't use /dev/tty");
124 		return (-1);
125 	}
126 
127 	if (!(c->flags & CLIENT_TERMINAL)) {
128 		*cause = xstrdup("not a terminal");
129 		return (-1);
130 	}
131 
132 	if (tty_open(&c->tty, cause) != 0)
133 		return (-1);
134 
135 	return (0);
136 }
137 
138 /* Lost a client. */
139 void
140 server_client_lost(struct client *c)
141 {
142 	struct message_entry	*msg;
143 	u_int			 i;
144 
145 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
146 		if (ARRAY_ITEM(&clients, i) == c)
147 			ARRAY_SET(&clients, i, NULL);
148 	}
149 	log_debug("lost client %d", c->ibuf.fd);
150 
151 	/*
152 	 * If CLIENT_TERMINAL hasn't been set, then tty_init hasn't been called
153 	 * and tty_free might close an unrelated fd.
154 	 */
155 	if (c->flags & CLIENT_TERMINAL)
156 		tty_free(&c->tty);
157 	free(c->ttyname);
158 	free(c->term);
159 
160 	evbuffer_free(c->stdin_data);
161 	evbuffer_free(c->stdout_data);
162 	if (c->stderr_data != c->stdout_data)
163 		evbuffer_free(c->stderr_data);
164 
165 	status_free_jobs(&c->status_new);
166 	status_free_jobs(&c->status_old);
167 	screen_free(&c->status);
168 
169 	free(c->title);
170 	close(c->cwd);
171 
172 	evtimer_del(&c->repeat_timer);
173 
174 	if (event_initialized(&c->identify_timer))
175 		evtimer_del(&c->identify_timer);
176 
177 	free(c->message_string);
178 	if (event_initialized(&c->message_timer))
179 		evtimer_del(&c->message_timer);
180 	for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
181 		msg = &ARRAY_ITEM(&c->message_log, i);
182 		free(msg->msg);
183 	}
184 	ARRAY_FREE(&c->message_log);
185 
186 	free(c->prompt_string);
187 	free(c->prompt_buffer);
188 
189 	c->cmdq->dead = 1;
190 	cmdq_free(c->cmdq);
191 	c->cmdq = NULL;
192 
193 	environ_free(&c->environ);
194 
195 	close(c->ibuf.fd);
196 	imsg_clear(&c->ibuf);
197 	if (event_initialized(&c->event))
198 		event_del(&c->event);
199 
200 	for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
201 		if (ARRAY_ITEM(&dead_clients, i) == NULL) {
202 			ARRAY_SET(&dead_clients, i, c);
203 			break;
204 		}
205 	}
206 	if (i == ARRAY_LENGTH(&dead_clients))
207 		ARRAY_ADD(&dead_clients, c);
208 	c->flags |= CLIENT_DEAD;
209 
210 	server_add_accept(0); /* may be more file descriptors now */
211 
212 	recalculate_sizes();
213 	server_check_unattached();
214 	server_update_socket();
215 }
216 
217 /* Process a single client event. */
218 void
219 server_client_callback(int fd, short events, void *data)
220 {
221 	struct client	*c = data;
222 
223 	if (c->flags & CLIENT_DEAD)
224 		return;
225 
226 	if (fd == c->ibuf.fd) {
227 		if (events & EV_WRITE && msgbuf_write(&c->ibuf.w) <= 0 &&
228 		    errno != EAGAIN)
229 			goto client_lost;
230 
231 		if (c->flags & CLIENT_BAD) {
232 			if (c->ibuf.w.queued == 0)
233 				goto client_lost;
234 			return;
235 		}
236 
237 		if (events & EV_READ && server_client_msg_dispatch(c) != 0)
238 			goto client_lost;
239 	}
240 
241 	server_push_stdout(c);
242 	server_push_stderr(c);
243 
244 	server_update_event(c);
245 	return;
246 
247 client_lost:
248 	server_client_lost(c);
249 }
250 
251 /* Handle client status timer. */
252 void
253 server_client_status_timer(void)
254 {
255 	struct client	*c;
256 	struct session	*s;
257 	struct timeval	 tv;
258 	u_int		 i;
259 	int		 interval;
260 	time_t		 difference;
261 
262 	if (gettimeofday(&tv, NULL) != 0)
263 		fatal("gettimeofday failed");
264 
265 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
266 		c = ARRAY_ITEM(&clients, i);
267 		if (c == NULL || c->session == NULL)
268 			continue;
269 		if (c->message_string != NULL || c->prompt_string != NULL) {
270 			/*
271 			 * Don't need timed redraw for messages/prompts so bail
272 			 * now. The status timer isn't reset when they are
273 			 * redrawn anyway.
274 			 */
275 			continue;
276 		}
277 		s = c->session;
278 
279 		if (!options_get_number(&s->options, "status"))
280 			continue;
281 		interval = options_get_number(&s->options, "status-interval");
282 
283 		difference = tv.tv_sec - c->status_timer.tv_sec;
284 		if (interval != 0 && difference >= interval) {
285 			status_update_jobs(c);
286 			c->flags |= CLIENT_STATUS;
287 		}
288 	}
289 }
290 
291 /* Check for mouse keys. */
292 void
293 server_client_check_mouse(struct client *c, struct window_pane *wp)
294 {
295 	struct session		*s = c->session;
296 	struct options		*oo = &s->options;
297 	struct mouse_event	*m = &c->tty.mouse;
298 	int			 statusat;
299 
300 	statusat = status_at_line(c);
301 
302 	/* Is this a window selection click on the status line? */
303 	if (statusat != -1 && m->y == (u_int)statusat &&
304 	    options_get_number(oo, "mouse-select-window")) {
305 		if (m->event & MOUSE_EVENT_CLICK) {
306 			status_set_window_at(c, m->x);
307 		} else if (m->event == MOUSE_EVENT_WHEEL) {
308 			if (m->wheel == MOUSE_WHEEL_UP)
309 				session_previous(c->session, 0);
310 			else if (m->wheel == MOUSE_WHEEL_DOWN)
311 				session_next(c->session, 0);
312 			server_redraw_session(s);
313 		}
314 		recalculate_sizes();
315 		return;
316 	}
317 
318 	/*
319 	 * Not on status line - adjust mouse position if status line is at the
320 	 * top and limit if at the bottom. From here on a struct mouse
321 	 * represents the offset onto the window itself.
322 	 */
323 	if (statusat == 0 && m->y > 0)
324 		m->y--;
325 	else if (statusat > 0 && m->y >= (u_int)statusat)
326 		m->y = statusat - 1;
327 
328 	/* Is this a pane selection? */
329 	if (options_get_number(oo, "mouse-select-pane") &&
330 	    (m->event == MOUSE_EVENT_DOWN || m->event == MOUSE_EVENT_WHEEL)) {
331 		window_set_active_at(wp->window, m->x, m->y);
332 		server_status_window(wp->window);
333 		server_redraw_window_borders(wp->window);
334 		wp = wp->window->active; /* may have changed */
335 	}
336 
337 	/* Check if trying to resize pane. */
338 	if (options_get_number(oo, "mouse-resize-pane"))
339 		layout_resize_pane_mouse(c);
340 
341 	/* Update last and pass through to client. */
342 	window_pane_mouse(wp, c->session, m);
343 }
344 
345 /* Is this fast enough to probably be a paste? */
346 int
347 server_client_assume_paste(struct session *s)
348 {
349 	struct timeval	tv;
350 	int		t;
351 
352 	if ((t = options_get_number(&s->options, "assume-paste-time")) == 0)
353 		return (0);
354 
355 	timersub(&s->activity_time, &s->last_activity_time, &tv);
356 	if (tv.tv_sec == 0 && tv.tv_usec < t * 1000)
357 		return (1);
358 	return (0);
359 }
360 
361 /* Handle data key input from client. */
362 void
363 server_client_handle_key(struct client *c, int key)
364 {
365 	struct session		*s;
366 	struct window		*w;
367 	struct window_pane	*wp;
368 	struct timeval		 tv;
369 	struct key_binding	*bd;
370 	int		      	 xtimeout, isprefix, ispaste;
371 
372 	/* Check the client is good to accept input. */
373 	if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
374 		return;
375 
376 	if (c->session == NULL)
377 		return;
378 	s = c->session;
379 
380 	/* Update the activity timer. */
381 	if (gettimeofday(&c->activity_time, NULL) != 0)
382 		fatal("gettimeofday failed");
383 
384 	memcpy(&s->last_activity_time, &s->activity_time,
385 	    sizeof s->last_activity_time);
386 	memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time);
387 
388 	w = c->session->curw->window;
389 	wp = w->active;
390 
391 	/* Special case: number keys jump to pane in identify mode. */
392 	if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') {
393 		if (c->flags & CLIENT_READONLY)
394 			return;
395 		window_unzoom(w);
396 		wp = window_pane_at_index(w, key - '0');
397 		if (wp != NULL && window_pane_visible(wp))
398 			window_set_active_pane(w, wp);
399 		server_clear_identify(c);
400 		return;
401 	}
402 
403 	/* Handle status line. */
404 	if (!(c->flags & CLIENT_READONLY)) {
405 		status_message_clear(c);
406 		server_clear_identify(c);
407 	}
408 	if (c->prompt_string != NULL) {
409 		if (!(c->flags & CLIENT_READONLY))
410 			status_prompt_key(c, key);
411 		return;
412 	}
413 
414 	/* Check for mouse keys. */
415 	if (key == KEYC_MOUSE) {
416 		if (c->flags & CLIENT_READONLY)
417 			return;
418 		server_client_check_mouse(c, wp);
419 		return;
420 	}
421 
422 	/* Is this a prefix key? */
423 	if (key == options_get_number(&s->options, "prefix"))
424 		isprefix = 1;
425 	else if (key == options_get_number(&s->options, "prefix2"))
426 		isprefix = 1;
427 	else
428 		isprefix = 0;
429 
430 	/* Treat prefix as a regular key when pasting is detected. */
431 	ispaste = server_client_assume_paste(s);
432 	if (ispaste)
433 		isprefix = 0;
434 
435 	/* No previous prefix key. */
436 	if (!(c->flags & CLIENT_PREFIX)) {
437 		if (isprefix) {
438 			c->flags |= CLIENT_PREFIX;
439 			server_status_client(c);
440 			return;
441 		}
442 
443 		/* Try as a non-prefix key binding. */
444 		if (ispaste || (bd = key_bindings_lookup(key)) == NULL) {
445 			if (!(c->flags & CLIENT_READONLY))
446 				window_pane_key(wp, s, key);
447 		} else
448 			key_bindings_dispatch(bd, c);
449 		return;
450 	}
451 
452 	/* Prefix key already pressed. Reset prefix and lookup key. */
453 	c->flags &= ~CLIENT_PREFIX;
454 	server_status_client(c);
455 	if ((bd = key_bindings_lookup(key | KEYC_PREFIX)) == NULL) {
456 		/* If repeating, treat this as a key, else ignore. */
457 		if (c->flags & CLIENT_REPEAT) {
458 			c->flags &= ~CLIENT_REPEAT;
459 			if (isprefix)
460 				c->flags |= CLIENT_PREFIX;
461 			else if (!(c->flags & CLIENT_READONLY))
462 				window_pane_key(wp, s, key);
463 		}
464 		return;
465 	}
466 
467 	/* If already repeating, but this key can't repeat, skip it. */
468 	if (c->flags & CLIENT_REPEAT && !bd->can_repeat) {
469 		c->flags &= ~CLIENT_REPEAT;
470 		if (isprefix)
471 			c->flags |= CLIENT_PREFIX;
472 		else if (!(c->flags & CLIENT_READONLY))
473 			window_pane_key(wp, s, key);
474 		return;
475 	}
476 
477 	/* If this key can repeat, reset the repeat flags and timer. */
478 	xtimeout = options_get_number(&s->options, "repeat-time");
479 	if (xtimeout != 0 && bd->can_repeat) {
480 		c->flags |= CLIENT_PREFIX|CLIENT_REPEAT;
481 
482 		tv.tv_sec = xtimeout / 1000;
483 		tv.tv_usec = (xtimeout % 1000) * 1000L;
484 		evtimer_del(&c->repeat_timer);
485 		evtimer_add(&c->repeat_timer, &tv);
486 	}
487 
488 	/* Dispatch the command. */
489 	key_bindings_dispatch(bd, c);
490 }
491 
492 /* Client functions that need to happen every loop. */
493 void
494 server_client_loop(void)
495 {
496 	struct client		*c;
497 	struct window		*w;
498 	struct window_pane	*wp;
499 	u_int		 	 i;
500 
501 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
502 		c = ARRAY_ITEM(&clients, i);
503 		if (c == NULL)
504 			continue;
505 
506 		server_client_check_exit(c);
507 		if (c->session != NULL) {
508 			server_client_check_redraw(c);
509 			server_client_reset_state(c);
510 		}
511 	}
512 
513 	/*
514 	 * Any windows will have been redrawn as part of clients, so clear
515 	 * their flags now. Also check pane focus and resize.
516 	 */
517 	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
518 		w = ARRAY_ITEM(&windows, i);
519 		if (w == NULL)
520 			continue;
521 
522 		w->flags &= ~WINDOW_REDRAW;
523 		TAILQ_FOREACH(wp, &w->panes, entry) {
524 			if (wp->fd != -1) {
525 				server_client_check_focus(wp);
526 				server_client_check_resize(wp);
527 			}
528 			wp->flags &= ~PANE_REDRAW;
529 		}
530 	}
531 }
532 
533 /* Check if pane should be resized. */
534 void
535 server_client_check_resize(struct window_pane *wp)
536 {
537 	struct winsize	ws;
538 
539 	if (!(wp->flags & PANE_RESIZE))
540 		return;
541 
542 	memset(&ws, 0, sizeof ws);
543 	ws.ws_col = wp->sx;
544 	ws.ws_row = wp->sy;
545 
546 	if (ioctl(wp->fd, TIOCSWINSZ, &ws) == -1)
547 		fatal("ioctl failed");
548 
549 	wp->flags &= ~PANE_RESIZE;
550 }
551 
552 /* Check whether pane should be focused. */
553 void
554 server_client_check_focus(struct window_pane *wp)
555 {
556 	u_int		 i;
557 	struct client	*c;
558 	int		 push;
559 
560 	/* Are focus events off? */
561 	if (!options_get_number(&global_options, "focus-events"))
562 		return;
563 
564 	/* Do we need to push the focus state? */
565 	push = wp->flags & PANE_FOCUSPUSH;
566 	wp->flags &= ~PANE_FOCUSPUSH;
567 
568 	/* If we don't care about focus, forget it. */
569 	if (!(wp->base.mode & MODE_FOCUSON))
570 		return;
571 
572 	/* If we're not the active pane in our window, we're not focused. */
573 	if (wp->window->active != wp)
574 		goto not_focused;
575 
576 	/* If we're in a mode, we're not focused. */
577 	if (wp->screen != &wp->base)
578 		goto not_focused;
579 
580 	/*
581 	 * If our window is the current window in any focused clients with an
582 	 * attached session, we're focused.
583 	 */
584 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
585 		c = ARRAY_ITEM(&clients, i);
586 		if (c == NULL || c->session == NULL)
587 			continue;
588 
589 		if (!(c->flags & CLIENT_FOCUSED))
590 			continue;
591 		if (c->session->flags & SESSION_UNATTACHED)
592 			continue;
593 
594 		if (c->session->curw->window == wp->window)
595 			goto focused;
596 	}
597 
598 not_focused:
599 	if (push || (wp->flags & PANE_FOCUSED))
600 		bufferevent_write(wp->event, "\033[O", 3);
601 	wp->flags &= ~PANE_FOCUSED;
602 	return;
603 
604 focused:
605 	if (push || !(wp->flags & PANE_FOCUSED))
606 		bufferevent_write(wp->event, "\033[I", 3);
607 	wp->flags |= PANE_FOCUSED;
608 }
609 
610 /*
611  * Update cursor position and mode settings. The scroll region and attributes
612  * are cleared when idle (waiting for an event) as this is the most likely time
613  * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a
614  * compromise between excessive resets and likelihood of an interrupt.
615  *
616  * tty_region/tty_reset/tty_update_mode already take care of not resetting
617  * things that are already in their default state.
618  */
619 void
620 server_client_reset_state(struct client *c)
621 {
622 	struct window		*w = c->session->curw->window;
623 	struct window_pane	*wp = w->active;
624 	struct screen		*s = wp->screen;
625 	struct options		*oo = &c->session->options;
626 	struct options		*wo = &w->options;
627 	int			 status, mode, o;
628 
629 	if (c->flags & CLIENT_SUSPENDED)
630 		return;
631 
632 	if (c->flags & CLIENT_CONTROL)
633 		return;
634 
635 	tty_region(&c->tty, 0, c->tty.sy - 1);
636 
637 	status = options_get_number(oo, "status");
638 	if (!window_pane_visible(wp) || wp->yoff + s->cy >= c->tty.sy - status)
639 		tty_cursor(&c->tty, 0, 0);
640 	else {
641 		o = status && options_get_number(oo, "status-position") == 0;
642 		tty_cursor(&c->tty, wp->xoff + s->cx, o + wp->yoff + s->cy);
643 	}
644 
645 	/*
646 	 * Resizing panes with the mouse requires at least button mode to give
647 	 * a smooth appearance.
648 	 */
649 	mode = s->mode;
650 	if ((c->tty.mouse.flags & MOUSE_RESIZE_PANE) &&
651 	    !(mode & MODE_MOUSE_BUTTON))
652 		mode |= MODE_MOUSE_BUTTON;
653 
654 	/*
655 	 * Any mode will do for mouse-select-pane, but set standard mode if
656 	 * none.
657 	 */
658 	if ((mode & ALL_MOUSE_MODES) == 0) {
659 		if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL &&
660 		    options_get_number(oo, "mouse-select-pane"))
661 			mode |= MODE_MOUSE_STANDARD;
662 		else if (options_get_number(oo, "mouse-resize-pane"))
663 			mode |= MODE_MOUSE_STANDARD;
664 		else if (options_get_number(oo, "mouse-select-window"))
665 			mode |= MODE_MOUSE_STANDARD;
666 		else if (options_get_number(wo, "mode-mouse"))
667 			mode |= MODE_MOUSE_STANDARD;
668 	}
669 
670 	/*
671 	 * Set UTF-8 mouse input if required. If the terminal is UTF-8, the
672 	 * user has set mouse-utf8 and any mouse mode is in effect, turn on
673 	 * UTF-8 mouse input. If the receiving terminal hasn't requested it
674 	 * (that is, it isn't in s->mode), then it'll be converted in
675 	 * input_mouse.
676 	 */
677 	if ((c->tty.flags & TTY_UTF8) &&
678 	    (mode & ALL_MOUSE_MODES) && options_get_number(oo, "mouse-utf8"))
679 		mode |= MODE_MOUSE_UTF8;
680 	else
681 		mode &= ~MODE_MOUSE_UTF8;
682 
683 	/* Set the terminal mode and reset attributes. */
684 	tty_update_mode(&c->tty, mode, s);
685 	tty_reset(&c->tty);
686 }
687 
688 /* Repeat time callback. */
689 void
690 server_client_repeat_timer(unused int fd, unused short events, void *data)
691 {
692 	struct client	*c = data;
693 
694 	if (c->flags & CLIENT_REPEAT) {
695 		if (c->flags & CLIENT_PREFIX)
696 			server_status_client(c);
697 		c->flags &= ~(CLIENT_PREFIX|CLIENT_REPEAT);
698 	}
699 }
700 
701 /* Check if client should be exited. */
702 void
703 server_client_check_exit(struct client *c)
704 {
705 	if (!(c->flags & CLIENT_EXIT))
706 		return;
707 
708 	if (EVBUFFER_LENGTH(c->stdin_data) != 0)
709 		return;
710 	if (EVBUFFER_LENGTH(c->stdout_data) != 0)
711 		return;
712 	if (EVBUFFER_LENGTH(c->stderr_data) != 0)
713 		return;
714 
715 	server_write_client(c, MSG_EXIT, &c->retval, sizeof c->retval);
716 	c->flags &= ~CLIENT_EXIT;
717 }
718 
719 /* Check for client redraws. */
720 void
721 server_client_check_redraw(struct client *c)
722 {
723 	struct session		*s = c->session;
724 	struct window_pane	*wp;
725 	int		 	 flags, redraw;
726 
727 	if (c->flags & (CLIENT_CONTROL|CLIENT_SUSPENDED))
728 		return;
729 
730 	flags = c->tty.flags & TTY_FREEZE;
731 	c->tty.flags &= ~TTY_FREEZE;
732 
733 	if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
734 		if (options_get_number(&s->options, "set-titles"))
735 			server_client_set_title(c);
736 
737 		if (c->message_string != NULL)
738 			redraw = status_message_redraw(c);
739 		else if (c->prompt_string != NULL)
740 			redraw = status_prompt_redraw(c);
741 		else
742 			redraw = status_redraw(c);
743 		if (!redraw)
744 			c->flags &= ~CLIENT_STATUS;
745 	}
746 
747 	if (c->flags & CLIENT_REDRAW) {
748 		screen_redraw_screen(c, 1, 1, 1);
749 		c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS);
750 	} else if (c->flags & CLIENT_REDRAWWINDOW) {
751 		TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry)
752 			screen_redraw_pane(c, wp);
753 		c->flags &= ~CLIENT_REDRAWWINDOW;
754 	} else {
755 		TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
756 			if (wp->flags & PANE_REDRAW)
757 				screen_redraw_pane(c, wp);
758 		}
759 	}
760 
761 	if (c->flags & CLIENT_BORDERS)
762 		screen_redraw_screen(c, 0, 0, 1);
763 
764 	if (c->flags & CLIENT_STATUS)
765 		screen_redraw_screen(c, 0, 1, 0);
766 
767 	c->tty.flags |= flags;
768 
769 	c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS|CLIENT_BORDERS);
770 }
771 
772 /* Set client title. */
773 void
774 server_client_set_title(struct client *c)
775 {
776 	struct session	*s = c->session;
777 	const char	*template;
778 	char		*title;
779 
780 	template = options_get_string(&s->options, "set-titles-string");
781 
782 	title = status_replace(c, NULL, NULL, NULL, template, time(NULL), 1);
783 	if (c->title == NULL || strcmp(title, c->title) != 0) {
784 		free(c->title);
785 		c->title = xstrdup(title);
786 		tty_set_title(&c->tty, c->title);
787 	}
788 	free(title);
789 }
790 
791 /* Dispatch message from client. */
792 int
793 server_client_msg_dispatch(struct client *c)
794 {
795 	struct imsg		 imsg;
796 	struct msg_stdin_data	 stdindata;
797 	const char		*data;
798 	ssize_t			 n, datalen;
799 
800 	if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
801 		return (-1);
802 
803 	for (;;) {
804 		if ((n = imsg_get(&c->ibuf, &imsg)) == -1)
805 			return (-1);
806 		if (n == 0)
807 			return (0);
808 
809 		data = imsg.data;
810 		datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
811 
812 		if (imsg.hdr.peerid != PROTOCOL_VERSION) {
813 			server_write_client(c, MSG_VERSION, NULL, 0);
814 			c->flags |= CLIENT_BAD;
815 			if (imsg.fd != -1)
816 				close(imsg.fd);
817 			imsg_free(&imsg);
818 			continue;
819 		}
820 
821 		log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd);
822 		switch (imsg.hdr.type) {
823 		case MSG_IDENTIFY_FLAGS:
824 		case MSG_IDENTIFY_TERM:
825 		case MSG_IDENTIFY_TTYNAME:
826 		case MSG_IDENTIFY_CWD:
827 		case MSG_IDENTIFY_STDIN:
828 		case MSG_IDENTIFY_ENVIRON:
829 		case MSG_IDENTIFY_DONE:
830 			server_client_msg_identify(c, &imsg);
831 			break;
832 		case MSG_COMMAND:
833 			server_client_msg_command(c, &imsg);
834 			break;
835 		case MSG_STDIN:
836 			if (datalen != sizeof stdindata)
837 				fatalx("bad MSG_STDIN size");
838 			memcpy(&stdindata, data, sizeof stdindata);
839 
840 			if (c->stdin_callback == NULL)
841 				break;
842 			if (stdindata.size <= 0)
843 				c->stdin_closed = 1;
844 			else {
845 				evbuffer_add(c->stdin_data, stdindata.data,
846 				    stdindata.size);
847 			}
848 			c->stdin_callback(c, c->stdin_closed,
849 			    c->stdin_callback_data);
850 			break;
851 		case MSG_RESIZE:
852 			if (datalen != 0)
853 				fatalx("bad MSG_RESIZE size");
854 
855 			if (c->flags & CLIENT_CONTROL)
856 				break;
857 			if (tty_resize(&c->tty)) {
858 				recalculate_sizes();
859 				server_redraw_client(c);
860 			}
861 			break;
862 		case MSG_EXITING:
863 			if (datalen != 0)
864 				fatalx("bad MSG_EXITING size");
865 
866 			c->session = NULL;
867 			tty_close(&c->tty);
868 			server_write_client(c, MSG_EXITED, NULL, 0);
869 			break;
870 		case MSG_WAKEUP:
871 		case MSG_UNLOCK:
872 			if (datalen != 0)
873 				fatalx("bad MSG_WAKEUP size");
874 
875 			if (!(c->flags & CLIENT_SUSPENDED))
876 				break;
877 			c->flags &= ~CLIENT_SUSPENDED;
878 
879 			if (c->tty.fd == -1) /* exited in the meantime */
880 				break;
881 
882 			if (gettimeofday(&c->activity_time, NULL) != 0)
883 				fatal("gettimeofday");
884 			if (c->session != NULL)
885 				session_update_activity(c->session);
886 
887 			tty_start_tty(&c->tty);
888 			server_redraw_client(c);
889 			recalculate_sizes();
890 			break;
891 		case MSG_SHELL:
892 			if (datalen != 0)
893 				fatalx("bad MSG_SHELL size");
894 
895 			server_client_msg_shell(c);
896 			break;
897 		}
898 
899 		imsg_free(&imsg);
900 	}
901 }
902 
903 /* Handle command message. */
904 void
905 server_client_msg_command(struct client *c, struct imsg *imsg)
906 {
907 	struct msg_command_data	  data;
908 	char			 *buf;
909 	size_t			  len;
910 	struct cmd_list		 *cmdlist = NULL;
911 	int			  argc;
912 	char			**argv, *cause;
913 
914 	if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
915 		fatalx("bad MSG_COMMAND size");
916 	memcpy(&data, imsg->data, sizeof data);
917 
918 	buf = (char *)imsg->data + sizeof data;
919 	len = imsg->hdr.len  - IMSG_HEADER_SIZE - sizeof data;
920 	if (len > 0 && buf[len - 1] != '\0')
921 		fatalx("bad MSG_COMMAND string");
922 
923 	argc = data.argc;
924 	if (cmd_unpack_argv(buf, len, argc, &argv) != 0) {
925 		cmdq_error(c->cmdq, "command too long");
926 		goto error;
927 	}
928 
929 	if (argc == 0) {
930 		argc = 1;
931 		argv = xcalloc(1, sizeof *argv);
932 		*argv = xstrdup("new-session");
933 	}
934 
935 	if ((cmdlist = cmd_list_parse(argc, argv, NULL, 0, &cause)) == NULL) {
936 		cmdq_error(c->cmdq, "%s", cause);
937 		cmd_free_argv(argc, argv);
938 		goto error;
939 	}
940 	cmd_free_argv(argc, argv);
941 
942 	if (c != cfg_client || cfg_finished)
943 		cmdq_run(c->cmdq, cmdlist);
944 	else
945 		cmdq_append(c->cmdq, cmdlist);
946 	cmd_list_free(cmdlist);
947 	return;
948 
949 error:
950 	if (cmdlist != NULL)
951 		cmd_list_free(cmdlist);
952 
953 	c->flags |= CLIENT_EXIT;
954 }
955 
956 /* Handle identify message. */
957 void
958 server_client_msg_identify(struct client *c, struct imsg *imsg)
959 {
960 	const char	*data;
961 	size_t	 	 datalen;
962 	int		 flags;
963 
964 	if (c->flags & CLIENT_IDENTIFIED)
965 		fatalx("out-of-order identify message");
966 
967 	data = imsg->data;
968 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
969 
970 	switch (imsg->hdr.type)	{
971 	case MSG_IDENTIFY_FLAGS:
972 		if (datalen != sizeof flags)
973 			fatalx("bad MSG_IDENTIFY_FLAGS size");
974 		memcpy(&flags, data, sizeof flags);
975 		c->flags |= flags;
976 		break;
977 	case MSG_IDENTIFY_TERM:
978 		if (datalen == 0 || data[datalen - 1] != '\0')
979 			fatalx("bad MSG_IDENTIFY_TERM string");
980 		c->term = xstrdup(data);
981 		break;
982 	case MSG_IDENTIFY_TTYNAME:
983 		if (datalen == 0 || data[datalen - 1] != '\0')
984 			fatalx("bad MSG_IDENTIFY_TTYNAME string");
985 		c->ttyname = xstrdup(data);
986 		break;
987 	case MSG_IDENTIFY_CWD:
988 		if (datalen != 0)
989 			fatalx("bad MSG_IDENTIFY_CWD size");
990 		c->cwd = imsg->fd;
991 		break;
992 	case MSG_IDENTIFY_STDIN:
993 		if (datalen != 0)
994 			fatalx("bad MSG_IDENTIFY_STDIN size");
995 		c->fd = imsg->fd;
996 		break;
997 	case MSG_IDENTIFY_ENVIRON:
998 		if (datalen == 0 || data[datalen - 1] != '\0')
999 			fatalx("bad MSG_IDENTIFY_ENVIRON string");
1000 		if (strchr(data, '=') != NULL)
1001 			environ_put(&c->environ, data);
1002 		break;
1003 	default:
1004 		break;
1005 	}
1006 
1007 	if (imsg->hdr.type != MSG_IDENTIFY_DONE)
1008 		return;
1009 	c->flags |= CLIENT_IDENTIFIED;
1010 
1011 #ifdef __CYGWIN__
1012 	c->fd = open(c->ttyname, O_RDWR|O_NOCTTY);
1013 	c->cwd = open(".", O_RDONLY);
1014 #endif
1015 
1016 	if (c->flags & CLIENT_CONTROL) {
1017 		c->stdin_callback = control_callback;
1018 
1019 		evbuffer_free(c->stderr_data);
1020 		c->stderr_data = c->stdout_data;
1021 
1022 		if (c->flags & CLIENT_CONTROLCONTROL)
1023 			evbuffer_add_printf(c->stdout_data, "\033P1000p");
1024 		server_write_client(c, MSG_STDIN, NULL, 0);
1025 
1026 		c->tty.fd = -1;
1027 		c->tty.log_fd = -1;
1028 
1029 		close(c->fd);
1030 		c->fd = -1;
1031 
1032 		return;
1033 	}
1034 
1035 	if (c->fd == -1)
1036 		return;
1037 	if (!isatty(c->fd)) {
1038 		close(c->fd);
1039 		c->fd = -1;
1040 		return;
1041 	}
1042 	tty_init(&c->tty, c, c->fd, c->term);
1043 	if (c->flags & CLIENT_UTF8)
1044 		c->tty.flags |= TTY_UTF8;
1045 	if (c->flags & CLIENT_256COLOURS)
1046 		c->tty.term_flags |= TERM_256COLOURS;
1047 
1048 	tty_resize(&c->tty);
1049 
1050 	if (!(c->flags & CLIENT_CONTROL))
1051 		c->flags |= CLIENT_TERMINAL;
1052 }
1053 
1054 /* Handle shell message. */
1055 void
1056 server_client_msg_shell(struct client *c)
1057 {
1058 	const char	*shell;
1059 
1060 	shell = options_get_string(&global_s_options, "default-shell");
1061 	if (*shell == '\0' || areshell(shell))
1062 		shell = _PATH_BSHELL;
1063 	server_write_client(c, MSG_SHELL, shell, strlen(shell) + 1);
1064 
1065 	c->flags |= CLIENT_BAD;	/* it will die after exec */
1066 }
1067