xref: /netbsd-src/external/bsd/tmux/dist/server-client.c (revision ba65fde2d7fefa7d39838fa5fa855e62bd606b5e)
1 /* $Id: server-client.c,v 1.1.1.2 2011/08/17 18:40:05 jmmv 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 
21 #include <event.h>
22 #include <fcntl.h>
23 #include <string.h>
24 #include <time.h>
25 #include <unistd.h>
26 
27 #include "tmux.h"
28 
29 void	server_client_handle_key(int, struct mouse_event *, void *);
30 void	server_client_repeat_timer(int, short, void *);
31 void	server_client_check_exit(struct client *);
32 void	server_client_check_backoff(struct client *);
33 void	server_client_check_redraw(struct client *);
34 void	server_client_set_title(struct client *);
35 void	server_client_reset_state(struct client *);
36 void	server_client_in_callback(struct bufferevent *, short, void *);
37 void	server_client_out_callback(struct bufferevent *, short, void *);
38 void	server_client_err_callback(struct bufferevent *, short, void *);
39 
40 int	server_client_msg_dispatch(struct client *);
41 void	server_client_msg_command(struct client *, struct msg_command_data *);
42 void	server_client_msg_identify(
43 	    struct client *, struct msg_identify_data *, int);
44 void	server_client_msg_shell(struct client *);
45 
46 void printflike2 server_client_msg_error(struct cmd_ctx *, const char *, ...);
47 void printflike2 server_client_msg_print(struct cmd_ctx *, const char *, ...);
48 void printflike2 server_client_msg_info(struct cmd_ctx *, const char *, ...);
49 
50 /* Create a new client. */
51 void
52 server_client_create(int fd)
53 {
54 	struct client	*c;
55 	u_int		 i;
56 
57 	setblocking(fd, 0);
58 
59 	c = xcalloc(1, sizeof *c);
60 	c->references = 0;
61 	imsg_init(&c->ibuf, fd);
62 	server_update_event(c);
63 
64 	if (gettimeofday(&c->creation_time, NULL) != 0)
65 		fatal("gettimeofday failed");
66 	memcpy(&c->activity_time, &c->creation_time, sizeof c->activity_time);
67 
68 	c->stdin_event = NULL;
69 	c->stdout_event = NULL;
70 	c->stderr_event = NULL;
71 
72 	c->tty.fd = -1;
73 	c->title = NULL;
74 
75 	c->session = NULL;
76 	c->last_session = NULL;
77 	c->tty.sx = 80;
78 	c->tty.sy = 24;
79 
80 	screen_init(&c->status, c->tty.sx, 1, 0);
81 	RB_INIT(&c->status_new);
82 	RB_INIT(&c->status_old);
83 
84 	c->message_string = NULL;
85 	ARRAY_INIT(&c->message_log);
86 
87 	c->prompt_string = NULL;
88 	c->prompt_buffer = NULL;
89 	c->prompt_index = 0;
90 
91 	c->last_mouse.b = MOUSE_UP;
92 	c->last_mouse.x = c->last_mouse.y = -1;
93 
94 	evtimer_set(&c->repeat_timer, server_client_repeat_timer, c);
95 
96 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
97 		if (ARRAY_ITEM(&clients, i) == NULL) {
98 			ARRAY_SET(&clients, i, c);
99 			return;
100 		}
101 	}
102 	ARRAY_ADD(&clients, c);
103 	log_debug("new client %d", fd);
104 }
105 
106 /* Lost a client. */
107 void
108 server_client_lost(struct client *c)
109 {
110 	struct message_entry	*msg;
111 	u_int			 i;
112 
113 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
114 		if (ARRAY_ITEM(&clients, i) == c)
115 			ARRAY_SET(&clients, i, NULL);
116 	}
117 	log_debug("lost client %d", c->ibuf.fd);
118 
119 	/*
120 	 * If CLIENT_TERMINAL hasn't been set, then tty_init hasn't been called
121 	 * and tty_free might close an unrelated fd.
122 	 */
123 	if (c->flags & CLIENT_TERMINAL)
124 		tty_free(&c->tty);
125 
126 	if (c->stdin_fd != -1) {
127 		setblocking(c->stdin_fd, 1);
128 		close(c->stdin_fd);
129 	}
130 	if (c->stdin_event != NULL)
131 		bufferevent_free(c->stdin_event);
132 	if (c->stdout_fd != -1) {
133 		setblocking(c->stdout_fd, 1);
134 		close(c->stdout_fd);
135 	}
136 	if (c->stdout_event != NULL)
137 		bufferevent_free(c->stdout_event);
138 	if (c->stderr_fd != -1) {
139 		setblocking(c->stderr_fd, 1);
140 		close(c->stderr_fd);
141 	}
142 	if (c->stderr_event != NULL)
143 		bufferevent_free(c->stderr_event);
144 
145 	status_free_jobs(&c->status_new);
146 	status_free_jobs(&c->status_old);
147 	screen_free(&c->status);
148 
149 	if (c->title != NULL)
150 		xfree(c->title);
151 
152 	evtimer_del(&c->repeat_timer);
153 
154 	evtimer_del(&c->identify_timer);
155 
156 	if (c->message_string != NULL)
157 		xfree(c->message_string);
158 	evtimer_del(&c->message_timer);
159 	for (i = 0; i < ARRAY_LENGTH(&c->message_log); i++) {
160 		msg = &ARRAY_ITEM(&c->message_log, i);
161 		xfree(msg->msg);
162 	}
163 	ARRAY_FREE(&c->message_log);
164 
165 	if (c->prompt_string != NULL)
166 		xfree(c->prompt_string);
167 	if (c->prompt_buffer != NULL)
168 		xfree(c->prompt_buffer);
169 
170 	if (c->cwd != NULL)
171 		xfree(c->cwd);
172 
173 	close(c->ibuf.fd);
174 	imsg_clear(&c->ibuf);
175 	event_del(&c->event);
176 
177 	for (i = 0; i < ARRAY_LENGTH(&dead_clients); i++) {
178 		if (ARRAY_ITEM(&dead_clients, i) == NULL) {
179 			ARRAY_SET(&dead_clients, i, c);
180 			break;
181 		}
182 	}
183 	if (i == ARRAY_LENGTH(&dead_clients))
184 		ARRAY_ADD(&dead_clients, c);
185 	c->flags |= CLIENT_DEAD;
186 
187 	recalculate_sizes();
188 	server_check_unattached();
189 	server_update_socket();
190 }
191 
192 /* Process a single client event. */
193 void
194 server_client_callback(int fd, short events, void *data)
195 {
196 	struct client	*c = data;
197 
198 	if (c->flags & CLIENT_DEAD)
199 		return;
200 
201 	if (fd == c->ibuf.fd) {
202 		if (events & EV_WRITE && msgbuf_write(&c->ibuf.w) < 0)
203 			goto client_lost;
204 
205 		if (c->flags & CLIENT_BAD) {
206 			if (c->ibuf.w.queued == 0)
207 				goto client_lost;
208 			return;
209 		}
210 
211 		if (events & EV_READ && server_client_msg_dispatch(c) != 0)
212 			goto client_lost;
213 	}
214 
215 	server_update_event(c);
216 	return;
217 
218 client_lost:
219 	server_client_lost(c);
220 }
221 
222 /* Handle client status timer. */
223 void
224 server_client_status_timer(void)
225 {
226 	struct client	*c;
227 	struct session	*s;
228 	struct timeval	 tv;
229 	u_int		 i;
230 	int		 interval;
231 	time_t		 difference;
232 
233 	if (gettimeofday(&tv, NULL) != 0)
234 		fatal("gettimeofday failed");
235 
236 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
237 		c = ARRAY_ITEM(&clients, i);
238 		if (c == NULL || c->session == NULL)
239 			continue;
240 		if (c->message_string != NULL || c->prompt_string != NULL) {
241 			/*
242 			 * Don't need timed redraw for messages/prompts so bail
243 			 * now. The status timer isn't reset when they are
244 			 * redrawn anyway.
245 			 */
246 			continue;
247 		}
248 		s = c->session;
249 
250 		if (!options_get_number(&s->options, "status"))
251 			continue;
252 		interval = options_get_number(&s->options, "status-interval");
253 
254 		difference = tv.tv_sec - c->status_timer.tv_sec;
255 		if (difference >= interval) {
256 			status_update_jobs(c);
257 			c->flags |= CLIENT_STATUS;
258 		}
259 	}
260 }
261 
262 /* Handle data key input from client. */
263 void
264 server_client_handle_key(int key, struct mouse_event *mouse, void *data)
265 {
266 	struct client		*c = data;
267 	struct session		*s;
268 	struct window		*w;
269 	struct window_pane	*wp;
270 	struct options		*oo;
271 	struct timeval		 tv;
272 	struct key_binding	*bd;
273 	struct keylist		*keylist;
274 	int		      	 xtimeout, isprefix;
275 	u_int			 i;
276 
277 	/* Check the client is good to accept input. */
278 	if ((c->flags & (CLIENT_DEAD|CLIENT_SUSPENDED)) != 0)
279 		return;
280 	if (c->session == NULL)
281 		return;
282 	s = c->session;
283 
284 	/* Update the activity timer. */
285 	if (gettimeofday(&c->activity_time, NULL) != 0)
286 		fatal("gettimeofday failed");
287 	memcpy(&s->activity_time, &c->activity_time, sizeof s->activity_time);
288 
289 	w = c->session->curw->window;
290 	wp = w->active;
291 	oo = &c->session->options;
292 
293 	/* Special case: number keys jump to pane in identify mode. */
294 	if (c->flags & CLIENT_IDENTIFY && key >= '0' && key <= '9') {
295 		if (c->flags & CLIENT_READONLY)
296 			return;
297 		wp = window_pane_at_index(w, key - '0');
298 		if (wp != NULL && window_pane_visible(wp))
299 			window_set_active_pane(w, wp);
300 		server_clear_identify(c);
301 		return;
302 	}
303 
304 	/* Handle status line. */
305 	if (!(c->flags & CLIENT_READONLY)) {
306 		status_message_clear(c);
307 		server_clear_identify(c);
308 	}
309 	if (c->prompt_string != NULL) {
310 		if (!(c->flags & CLIENT_READONLY))
311 			status_prompt_key(c, key);
312 		return;
313 	}
314 
315 	/* Check for mouse keys. */
316 	if (key == KEYC_MOUSE) {
317 		if (c->flags & CLIENT_READONLY)
318 			return;
319 		if (options_get_number(oo, "mouse-select-pane") &&
320 		    ((!(mouse->b & MOUSE_DRAG) && mouse->b != MOUSE_UP) ||
321 		    wp->mode != &window_copy_mode)) {
322 			/*
323 			 * Allow pane switching in copy mode only by mouse down
324 			 * (click).
325 			 */
326 			window_set_active_at(w, mouse->x, mouse->y);
327 			server_redraw_window_borders(w);
328 			wp = w->active;
329 		}
330 		if (mouse->y + 1 == c->tty.sy &&
331 		    options_get_number(oo, "mouse-select-window") &&
332 		    options_get_number(oo, "status")) {
333 			if (mouse->b == MOUSE_UP &&
334 			    c->last_mouse.b != MOUSE_UP) {
335 				status_set_window_at(c, mouse->x);
336 				return;
337 			}
338 			if (mouse->b & MOUSE_45) {
339 				if ((mouse->b & MOUSE_BUTTON) == MOUSE_1) {
340 					session_previous(c->session, 0);
341 					server_redraw_session(s);
342 				}
343 				if ((mouse->b & MOUSE_BUTTON) == MOUSE_2) {
344 					session_next(c->session, 0);
345 					server_redraw_session(s);
346 				}
347 				return;
348 			}
349 		}
350 		if (options_get_number(oo, "mouse-resize-pane"))
351 			layout_resize_pane_mouse(c, mouse);
352 		memcpy(&c->last_mouse, mouse, sizeof c->last_mouse);
353 		window_pane_mouse(wp, c->session, mouse);
354 		return;
355 	}
356 
357 	/* Is this a prefix key? */
358 	keylist = options_get_data(&c->session->options, "prefix");
359 	isprefix = 0;
360 	for (i = 0; i < ARRAY_LENGTH(keylist); i++) {
361 		if (key == ARRAY_ITEM(keylist, i)) {
362 			isprefix = 1;
363 			break;
364 		}
365 	}
366 
367 	/* No previous prefix key. */
368 	if (!(c->flags & CLIENT_PREFIX)) {
369 		if (isprefix)
370 			c->flags |= CLIENT_PREFIX;
371 		else {
372 			/* Try as a non-prefix key binding. */
373 			if ((bd = key_bindings_lookup(key)) == NULL) {
374 				if (!(c->flags & CLIENT_READONLY))
375 					window_pane_key(wp, c->session, key);
376 			} else
377 				key_bindings_dispatch(bd, c);
378 		}
379 		return;
380 	}
381 
382 	/* Prefix key already pressed. Reset prefix and lookup key. */
383 	c->flags &= ~CLIENT_PREFIX;
384 	if ((bd = key_bindings_lookup(key | KEYC_PREFIX)) == NULL) {
385 		/* If repeating, treat this as a key, else ignore. */
386 		if (c->flags & CLIENT_REPEAT) {
387 			c->flags &= ~CLIENT_REPEAT;
388 			if (isprefix)
389 				c->flags |= CLIENT_PREFIX;
390 			else if (!(c->flags & CLIENT_READONLY))
391 				window_pane_key(wp, c->session, key);
392 		}
393 		return;
394 	}
395 
396 	/* If already repeating, but this key can't repeat, skip it. */
397 	if (c->flags & CLIENT_REPEAT && !bd->can_repeat) {
398 		c->flags &= ~CLIENT_REPEAT;
399 		if (isprefix)
400 			c->flags |= CLIENT_PREFIX;
401 		else if (!(c->flags & CLIENT_READONLY))
402 			window_pane_key(wp, c->session, key);
403 		return;
404 	}
405 
406 	/* If this key can repeat, reset the repeat flags and timer. */
407 	xtimeout = options_get_number(&c->session->options, "repeat-time");
408 	if (xtimeout != 0 && bd->can_repeat) {
409 		c->flags |= CLIENT_PREFIX|CLIENT_REPEAT;
410 
411 		tv.tv_sec = xtimeout / 1000;
412 		tv.tv_usec = (xtimeout % 1000) * 1000L;
413 		evtimer_del(&c->repeat_timer);
414 		evtimer_add(&c->repeat_timer, &tv);
415 	}
416 
417 	/* Dispatch the command. */
418 	key_bindings_dispatch(bd, c);
419 }
420 
421 /* Client functions that need to happen every loop. */
422 void
423 server_client_loop(void)
424 {
425 	struct client		*c;
426 	struct window		*w;
427 	struct window_pane	*wp;
428 	u_int		 	 i;
429 
430 	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
431 		c = ARRAY_ITEM(&clients, i);
432 		if (c == NULL)
433 			continue;
434 
435 		server_client_check_exit(c);
436 		if (c->session != NULL) {
437 			server_client_check_redraw(c);
438 			server_client_reset_state(c);
439 		}
440 	}
441 
442 	/*
443 	 * Any windows will have been redrawn as part of clients, so clear
444 	 * their flags now.
445 	 */
446 	for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
447 		w = ARRAY_ITEM(&windows, i);
448 		if (w == NULL)
449 			continue;
450 
451 		w->flags &= ~WINDOW_REDRAW;
452 		TAILQ_FOREACH(wp, &w->panes, entry)
453 			wp->flags &= ~PANE_REDRAW;
454 	}
455 }
456 
457 /*
458  * Update cursor position and mode settings. The scroll region and attributes
459  * are cleared when idle (waiting for an event) as this is the most likely time
460  * a user may interrupt tmux, for example with ~^Z in ssh(1). This is a
461  * compromise between excessive resets and likelihood of an interrupt.
462  *
463  * tty_region/tty_reset/tty_update_mode already take care of not resetting
464  * things that are already in their default state.
465  */
466 void
467 server_client_reset_state(struct client *c)
468 {
469 	struct window		*w = c->session->curw->window;
470 	struct window_pane	*wp = w->active;
471 	struct screen		*s = wp->screen;
472 	struct options		*oo = &c->session->options;
473 	struct options		*wo = &w->options;
474 	int			 status, mode;
475 
476 	if (c->flags & CLIENT_SUSPENDED)
477 		return;
478 
479 	tty_region(&c->tty, 0, c->tty.sy - 1);
480 
481 	status = options_get_number(oo, "status");
482 	if (!window_pane_visible(wp) || wp->yoff + s->cy >= c->tty.sy - status)
483 		tty_cursor(&c->tty, 0, 0);
484 	else
485 		tty_cursor(&c->tty, wp->xoff + s->cx, wp->yoff + s->cy);
486 
487 	/*
488 	 * Resizing panes with the mouse requires at least button mode to give
489 	 * a smooth appearance.
490 	 */
491 	mode = s->mode;
492 	if ((c->last_mouse.b & MOUSE_RESIZE_PANE) &&
493 	    !(mode & (MODE_MOUSE_BUTTON|MODE_MOUSE_ANY)))
494 		mode |= MODE_MOUSE_BUTTON;
495 
496 	/*
497 	 * Any mode will do for mouse-select-pane, but set standard mode if
498 	 * none.
499 	 */
500 	if ((mode & ALL_MOUSE_MODES) == 0) {
501 		if (TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry) != NULL &&
502 		    options_get_number(oo, "mouse-select-pane"))
503 			mode |= MODE_MOUSE_STANDARD;
504 		else if (options_get_number(oo, "mouse-resize-pane"))
505 			mode |= MODE_MOUSE_STANDARD;
506 		else if (options_get_number(oo, "mouse-select-window"))
507 			mode |= MODE_MOUSE_STANDARD;
508 		else if (options_get_number(wo, "mode-mouse"))
509 			mode |= MODE_MOUSE_STANDARD;
510 	}
511 
512 	/*
513 	 * Set UTF-8 mouse input if required. If the terminal is UTF-8, the
514 	 * user has set mouse-utf8 and any mouse mode is in effect, turn on
515 	 * UTF-8 mouse input. If the receiving terminal hasn't requested it
516 	 * (that is, it isn't in s->mode), then it'll be converted in
517 	 * input_mouse.
518 	 */
519 	if ((c->tty.flags & TTY_UTF8) &&
520 	    (mode & ALL_MOUSE_MODES) && options_get_number(oo, "mouse-utf8"))
521 		mode |= MODE_MOUSE_UTF8;
522 	else
523 		mode &= ~MODE_MOUSE_UTF8;
524 
525 	/* Set the terminal mode and reset attributes. */
526 	tty_update_mode(&c->tty, mode, s);
527 	tty_reset(&c->tty);
528 }
529 
530 /* Repeat time callback. */
531 /* ARGSUSED */
532 void
533 server_client_repeat_timer(unused int fd, unused short events, void *data)
534 {
535 	struct client	*c = data;
536 
537 	if (c->flags & CLIENT_REPEAT)
538 		c->flags &= ~(CLIENT_PREFIX|CLIENT_REPEAT);
539 }
540 
541 /* Check if client should be exited. */
542 void
543 server_client_check_exit(struct client *c)
544 {
545 	struct msg_exit_data	exitdata;
546 
547 	if (!(c->flags & CLIENT_EXIT))
548 		return;
549 
550 	if (c->stdout_fd != -1 && c->stdout_event != NULL &&
551 	    EVBUFFER_LENGTH(c->stdout_event->output) != 0)
552 		return;
553 	if (c->stderr_fd != -1 && c->stderr_event != NULL &&
554 	    EVBUFFER_LENGTH(c->stderr_event->output) != 0)
555 		return;
556 
557 	exitdata.retcode = c->retcode;
558 	server_write_client(c, MSG_EXIT, &exitdata, sizeof exitdata);
559 
560 	c->flags &= ~CLIENT_EXIT;
561 }
562 
563 /*
564  * Check if the client should backoff. During backoff, data from external
565  * programs is not written to the terminal. When the existing data drains, the
566  * client is redrawn.
567  *
568  * There are two backoff phases - both the tty and client have backoff flags -
569  * the first to allow existing data to drain and the latter to ensure backoff
570  * is disabled until the redraw has finished and prevent the redraw triggering
571  * another backoff.
572  */
573 void
574 server_client_check_backoff(struct client *c)
575 {
576 	struct tty	*tty = &c->tty;
577 	size_t		 used;
578 
579 	used = EVBUFFER_LENGTH(tty->event->output);
580 
581 	/*
582 	 * If in the second backoff phase (redrawing), don't check backoff
583 	 * until the redraw has completed (or enough of it to drop below the
584 	 * backoff threshold).
585 	 */
586 	if (c->flags & CLIENT_BACKOFF) {
587 		if (used > BACKOFF_THRESHOLD)
588 			return;
589 		c->flags &= ~CLIENT_BACKOFF;
590 		return;
591 	}
592 
593 	/* Once drained, allow data through again and schedule redraw. */
594 	if (tty->flags & TTY_BACKOFF) {
595 		if (used != 0)
596 			return;
597 		tty->flags &= ~TTY_BACKOFF;
598 		c->flags |= (CLIENT_BACKOFF|CLIENT_REDRAWWINDOW|CLIENT_STATUS);
599 		return;
600 	}
601 
602 	/* If too much data, start backoff. */
603 	if (used > BACKOFF_THRESHOLD)
604 		tty->flags |= TTY_BACKOFF;
605 }
606 
607 /* Check for client redraws. */
608 void
609 server_client_check_redraw(struct client *c)
610 {
611 	struct session		*s = c->session;
612 	struct window_pane	*wp;
613 	int		 	 flags, redraw;
614 
615 	flags = c->tty.flags & TTY_FREEZE;
616 	c->tty.flags &= ~TTY_FREEZE;
617 
618 	if (c->flags & (CLIENT_REDRAW|CLIENT_STATUS)) {
619 		if (options_get_number(&s->options, "set-titles"))
620 			server_client_set_title(c);
621 
622 		if (c->message_string != NULL)
623 			redraw = status_message_redraw(c);
624 		else if (c->prompt_string != NULL)
625 			redraw = status_prompt_redraw(c);
626 		else
627 			redraw = status_redraw(c);
628 		if (!redraw)
629 			c->flags &= ~CLIENT_STATUS;
630 	}
631 
632 	if (c->flags & CLIENT_REDRAW) {
633 		screen_redraw_screen(c, 0, 0);
634 		c->flags &= ~(CLIENT_STATUS|CLIENT_BORDERS);
635 	} else if (c->flags & CLIENT_REDRAWWINDOW) {
636 		TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry)
637 			screen_redraw_pane(c, wp);
638 		c->flags &= ~CLIENT_REDRAWWINDOW;
639 	} else {
640 		TAILQ_FOREACH(wp, &c->session->curw->window->panes, entry) {
641 			if (wp->flags & PANE_REDRAW)
642 				screen_redraw_pane(c, wp);
643 		}
644 	}
645 
646 	if (c->flags & CLIENT_BORDERS)
647 		screen_redraw_screen(c, 0, 1);
648 
649 	if (c->flags & CLIENT_STATUS)
650 		screen_redraw_screen(c, 1, 0);
651 
652 	c->tty.flags |= flags;
653 
654 	c->flags &= ~(CLIENT_REDRAW|CLIENT_STATUS|CLIENT_BORDERS);
655 }
656 
657 /* Set client title. */
658 void
659 server_client_set_title(struct client *c)
660 {
661 	struct session	*s = c->session;
662 	const char	*template;
663 	char		*title;
664 
665 	template = options_get_string(&s->options, "set-titles-string");
666 
667 	title = status_replace(c, NULL, NULL, NULL, template, time(NULL), 1);
668 	if (c->title == NULL || strcmp(title, c->title) != 0) {
669 		if (c->title != NULL)
670 			xfree(c->title);
671 		c->title = xstrdup(title);
672 		tty_set_title(&c->tty, c->title);
673 	}
674 	xfree(title);
675 }
676 
677 /*
678  * Error callback for client stdin. Caller must increase reference count when
679  * enabling event!
680  */
681 void
682 server_client_in_callback(
683     unused struct bufferevent *bufev, unused short what, void *data)
684 {
685 	struct client	*c = data;
686 
687 	c->references--;
688 	if (c->flags & CLIENT_DEAD)
689 		return;
690 
691 	bufferevent_disable(c->stdin_event, EV_READ|EV_WRITE);
692 	setblocking(c->stdin_fd, 1);
693 	close(c->stdin_fd);
694 	c->stdin_fd = -1;
695 
696 	if (c->stdin_callback != NULL)
697 		c->stdin_callback(c, c->stdin_data);
698 }
699 
700 /* Error callback for client stdout. */
701 void
702 server_client_out_callback(
703     unused struct bufferevent *bufev, unused short what, unused void *data)
704 {
705 	struct client	*c = data;
706 
707 	bufferevent_disable(c->stdout_event, EV_READ|EV_WRITE);
708 	setblocking(c->stdout_fd, 1);
709 	close(c->stdout_fd);
710 	c->stdout_fd = -1;
711 }
712 
713 /* Error callback for client stderr. */
714 void
715 server_client_err_callback(
716     unused struct bufferevent *bufev, unused short what, unused void *data)
717 {
718 	struct client	*c = data;
719 
720 	bufferevent_disable(c->stderr_event, EV_READ|EV_WRITE);
721 	setblocking(c->stderr_fd, 1);
722 	close(c->stderr_fd);
723 	c->stderr_fd = -1;
724 }
725 
726 /* Dispatch message from client. */
727 int
728 server_client_msg_dispatch(struct client *c)
729 {
730 	struct imsg		 imsg;
731 	struct msg_command_data	 commanddata;
732 	struct msg_identify_data identifydata;
733 	struct msg_environ_data	 environdata;
734 	ssize_t			 n, datalen;
735 
736 	if ((n = imsg_read(&c->ibuf)) == -1 || n == 0)
737 		return (-1);
738 
739 	for (;;) {
740 		if ((n = imsg_get(&c->ibuf, &imsg)) == -1)
741 			return (-1);
742 		if (n == 0)
743 			return (0);
744 		datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
745 
746 		if (imsg.hdr.peerid != PROTOCOL_VERSION) {
747 			server_write_client(c, MSG_VERSION, NULL, 0);
748 			c->flags |= CLIENT_BAD;
749 			imsg_free(&imsg);
750 			continue;
751 		}
752 
753 		log_debug("got %d from client %d", imsg.hdr.type, c->ibuf.fd);
754 		switch (imsg.hdr.type) {
755 		case MSG_COMMAND:
756 			if (datalen != sizeof commanddata)
757 				fatalx("bad MSG_COMMAND size");
758 			memcpy(&commanddata, imsg.data, sizeof commanddata);
759 
760 			server_client_msg_command(c, &commanddata);
761 			break;
762 		case MSG_IDENTIFY:
763 			if (datalen != sizeof identifydata)
764 				fatalx("bad MSG_IDENTIFY size");
765 			if (imsg.fd == -1)
766 				fatalx("MSG_IDENTIFY missing fd");
767 			memcpy(&identifydata, imsg.data, sizeof identifydata);
768 
769 			c->stdin_fd = imsg.fd;
770 			c->stdin_event = bufferevent_new(c->stdin_fd,
771 			    NULL, NULL, server_client_in_callback, c);
772 			if (c->stdin_event == NULL)
773 				fatalx("failed to create stdin event");
774 			setblocking(c->stdin_fd, 0);
775 
776 			server_client_msg_identify(c, &identifydata, imsg.fd);
777 			break;
778 		case MSG_STDOUT:
779 			if (datalen != 0)
780 				fatalx("bad MSG_STDOUT size");
781 			if (imsg.fd == -1)
782 				fatalx("MSG_STDOUT missing fd");
783 
784 			c->stdout_fd = imsg.fd;
785 			c->stdout_event = bufferevent_new(c->stdout_fd,
786 			    NULL, NULL, server_client_out_callback, c);
787 			if (c->stdout_event == NULL)
788 				fatalx("failed to create stdout event");
789 			setblocking(c->stdout_fd, 0);
790 
791 			break;
792 		case MSG_STDERR:
793 			if (datalen != 0)
794 				fatalx("bad MSG_STDERR size");
795 			if (imsg.fd == -1)
796 				fatalx("MSG_STDERR missing fd");
797 
798 			c->stderr_fd = imsg.fd;
799 			c->stderr_event = bufferevent_new(c->stderr_fd,
800 			    NULL, NULL, server_client_err_callback, c);
801 			if (c->stderr_event == NULL)
802 				fatalx("failed to create stderr event");
803 			setblocking(c->stderr_fd, 0);
804 
805 			break;
806 		case MSG_RESIZE:
807 			if (datalen != 0)
808 				fatalx("bad MSG_RESIZE size");
809 
810 			if (tty_resize(&c->tty)) {
811 				recalculate_sizes();
812 				server_redraw_client(c);
813 			}
814 			break;
815 		case MSG_EXITING:
816 			if (datalen != 0)
817 				fatalx("bad MSG_EXITING size");
818 
819 			c->session = NULL;
820 			tty_close(&c->tty);
821 			server_write_client(c, MSG_EXITED, NULL, 0);
822 			break;
823 		case MSG_WAKEUP:
824 		case MSG_UNLOCK:
825 			if (datalen != 0)
826 				fatalx("bad MSG_WAKEUP size");
827 
828 			if (!(c->flags & CLIENT_SUSPENDED))
829 				break;
830 			c->flags &= ~CLIENT_SUSPENDED;
831 
832 			if (gettimeofday(&c->activity_time, NULL) != 0)
833 				fatal("gettimeofday");
834 			if (c->session != NULL)
835 				session_update_activity(c->session);
836 
837 			tty_start_tty(&c->tty);
838 			server_redraw_client(c);
839 			recalculate_sizes();
840 			break;
841 		case MSG_ENVIRON:
842 			if (datalen != sizeof environdata)
843 				fatalx("bad MSG_ENVIRON size");
844 			memcpy(&environdata, imsg.data, sizeof environdata);
845 
846 			environdata.var[(sizeof environdata.var) - 1] = '\0';
847 			if (strchr(environdata.var, '=') != NULL)
848 				environ_put(&c->environ, environdata.var);
849 			break;
850 		case MSG_SHELL:
851 			if (datalen != 0)
852 				fatalx("bad MSG_SHELL size");
853 
854 			server_client_msg_shell(c);
855 			break;
856 		default:
857 			fatalx("unexpected message");
858 		}
859 
860 		imsg_free(&imsg);
861 	}
862 }
863 
864 /* Callback to send error message to client. */
865 void printflike2
866 server_client_msg_error(struct cmd_ctx *ctx, const char *fmt, ...)
867 {
868 	va_list	ap;
869 
870 	va_start(ap, fmt);
871 	evbuffer_add_vprintf(ctx->cmdclient->stderr_event->output, fmt, ap);
872 	va_end(ap);
873 
874 	bufferevent_write(ctx->cmdclient->stderr_event, "\n", 1);
875 	ctx->cmdclient->retcode = 1;
876 }
877 
878 /* Callback to send print message to client. */
879 void printflike2
880 server_client_msg_print(struct cmd_ctx *ctx, const char *fmt, ...)
881 {
882 	va_list	ap;
883 
884 	va_start(ap, fmt);
885 	evbuffer_add_vprintf(ctx->cmdclient->stdout_event->output, fmt, ap);
886 	va_end(ap);
887 
888 	bufferevent_write(ctx->cmdclient->stdout_event, "\n", 1);
889 }
890 
891 /* Callback to send print message to client, if not quiet. */
892 void printflike2
893 server_client_msg_info(struct cmd_ctx *ctx, const char *fmt, ...)
894 {
895 	va_list	ap;
896 
897 	if (options_get_number(&global_options, "quiet"))
898 		return;
899 
900 	va_start(ap, fmt);
901 	evbuffer_add_vprintf(ctx->cmdclient->stdout_event->output, fmt, ap);
902 	va_end(ap);
903 
904 	bufferevent_write(ctx->cmdclient->stdout_event, "\n", 1);
905 }
906 
907 /* Handle command message. */
908 void
909 server_client_msg_command(struct client *c, struct msg_command_data *data)
910 {
911 	struct cmd_ctx	 ctx;
912 	struct cmd_list	*cmdlist = NULL;
913 	int		 argc;
914 	char	       **argv, *cause;
915 
916 	ctx.error = server_client_msg_error;
917 	ctx.print = server_client_msg_print;
918 	ctx.info = server_client_msg_info;
919 
920 	ctx.msgdata = data;
921 	ctx.curclient = NULL;
922 
923 	ctx.cmdclient = c;
924 
925 	argc = data->argc;
926 	data->argv[(sizeof data->argv) - 1] = '\0';
927 	if (cmd_unpack_argv(data->argv, sizeof data->argv, argc, &argv) != 0) {
928 		server_client_msg_error(&ctx, "command too long");
929 		goto error;
930 	}
931 
932 	if (argc == 0) {
933 		argc = 1;
934 		argv = xcalloc(1, sizeof *argv);
935 		*argv = xstrdup("new-session");
936 	}
937 
938 	if ((cmdlist = cmd_list_parse(argc, argv, &cause)) == NULL) {
939 		server_client_msg_error(&ctx, "%s", cause);
940 		cmd_free_argv(argc, argv);
941 		goto error;
942 	}
943 	cmd_free_argv(argc, argv);
944 
945 	if (cmd_list_exec(cmdlist, &ctx) != 1)
946 		c->flags |= CLIENT_EXIT;
947 	cmd_list_free(cmdlist);
948 	return;
949 
950 error:
951 	if (cmdlist != NULL)
952 		cmd_list_free(cmdlist);
953 	c->flags |= CLIENT_EXIT;
954 }
955 
956 /* Handle identify message. */
957 void
958 server_client_msg_identify(
959     struct client *c, struct msg_identify_data *data, int fd)
960 {
961 	int	tty_fd;
962 
963 	c->cwd = NULL;
964 	data->cwd[(sizeof data->cwd) - 1] = '\0';
965 	if (*data->cwd != '\0')
966 		c->cwd = xstrdup(data->cwd);
967 
968 	if (!isatty(fd))
969 	    return;
970 	if ((tty_fd = dup(fd)) == -1)
971 		fatal("dup failed");
972 	data->term[(sizeof data->term) - 1] = '\0';
973 	tty_init(&c->tty, tty_fd, data->term);
974 	if (data->flags & IDENTIFY_UTF8)
975 		c->tty.flags |= TTY_UTF8;
976 	if (data->flags & IDENTIFY_256COLOURS)
977 		c->tty.term_flags |= TERM_256COLOURS;
978 	else if (data->flags & IDENTIFY_88COLOURS)
979 		c->tty.term_flags |= TERM_88COLOURS;
980 	c->tty.key_callback = server_client_handle_key;
981 	c->tty.key_data = c;
982 
983 	tty_resize(&c->tty);
984 
985 	c->flags |= CLIENT_TERMINAL;
986 }
987 
988 /* Handle shell message. */
989 void
990 server_client_msg_shell(struct client *c)
991 {
992 	struct msg_shell_data	 data;
993 	const char		*shell;
994 
995 	shell = options_get_string(&global_s_options, "default-shell");
996 
997 	if (*shell == '\0' || areshell(shell))
998 		shell = _PATH_BSHELL;
999 	if (strlcpy(data.shell, shell, sizeof data.shell) >= sizeof data.shell)
1000 		strlcpy(data.shell, _PATH_BSHELL, sizeof data.shell);
1001 
1002 	server_write_client(c, MSG_SHELL, &data, sizeof data);
1003 	c->flags |= CLIENT_BAD;	/* it will die after exec */
1004 }
1005