Home | History | Annotate | Line # | Download | only in dist
      1 /* $OpenBSD$ */
      2 
      3 /*
      4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) 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/socket.h>
     21 #include <sys/uio.h>
     22 #include <sys/un.h>
     23 #include <sys/wait.h>
     24 #include <sys/file.h>
     25 
     26 #include <errno.h>
     27 #include <fcntl.h>
     28 #include <signal.h>
     29 #include <stdlib.h>
     30 #include <string.h>
     31 #include <unistd.h>
     32 
     33 #include "tmux.h"
     34 
     35 static struct tmuxproc	*client_proc;
     36 static struct tmuxpeer	*client_peer;
     37 static uint64_t		 client_flags;
     38 static int		 client_suspended;
     39 static enum {
     40 	CLIENT_EXIT_NONE,
     41 	CLIENT_EXIT_DETACHED,
     42 	CLIENT_EXIT_DETACHED_HUP,
     43 	CLIENT_EXIT_LOST_TTY,
     44 	CLIENT_EXIT_TERMINATED,
     45 	CLIENT_EXIT_LOST_SERVER,
     46 	CLIENT_EXIT_EXITED,
     47 	CLIENT_EXIT_SERVER_EXITED,
     48 	CLIENT_EXIT_MESSAGE_PROVIDED
     49 } client_exitreason = CLIENT_EXIT_NONE;
     50 static int		 client_exitflag;
     51 static int		 client_exitval;
     52 static enum msgtype	 client_exittype;
     53 static const char	*client_exitsession;
     54 static char		*client_exitmessage;
     55 static const char	*client_execshell;
     56 static const char	*client_execcmd;
     57 static int		 client_attached;
     58 static struct client_files client_files = RB_INITIALIZER(&client_files);
     59 
     60 static __dead void	 client_exec(const char *,const char *);
     61 static int		 client_get_lock(char *);
     62 static int		 client_connect(struct event_base *, const char *,
     63 			     uint64_t);
     64 static void		 client_send_identify(const char *, const char *,
     65 			     char **, u_int, const char *, int);
     66 static void		 client_signal(int);
     67 static void		 client_dispatch(struct imsg *, void *);
     68 static void		 client_dispatch_attached(struct imsg *);
     69 static void		 client_dispatch_wait(struct imsg *);
     70 static const char	*client_exit_message(void);
     71 
     72 /*
     73  * Get server create lock. If already held then server start is happening in
     74  * another client, so block until the lock is released and return -2 to
     75  * retry. Return -1 on failure to continue and start the server anyway.
     76  */
     77 static int
     78 client_get_lock(char *lockfile)
     79 {
     80 	int lockfd;
     81 
     82 	log_debug("lock file is %s", lockfile);
     83 
     84 	if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) {
     85 		log_debug("open failed: %s", strerror(errno));
     86 		return (-1);
     87 	}
     88 
     89 	if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
     90 		log_debug("flock failed: %s", strerror(errno));
     91 		if (errno != EAGAIN)
     92 			return (lockfd);
     93 		while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR)
     94 			/* nothing */;
     95 		close(lockfd);
     96 		return (-2);
     97 	}
     98 	log_debug("flock succeeded");
     99 
    100 	return (lockfd);
    101 }
    102 
    103 /* Connect client to server. */
    104 static int
    105 client_connect(struct event_base *base, const char *path, uint64_t flags)
    106 {
    107 	struct sockaddr_un	sa;
    108 	size_t			size;
    109 	int			fd, lockfd = -1, locked = 0;
    110 	char		       *lockfile = NULL;
    111 
    112 	memset(&sa, 0, sizeof sa);
    113 	sa.sun_family = AF_UNIX;
    114 	size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
    115 	if (size >= sizeof sa.sun_path) {
    116 		errno = ENAMETOOLONG;
    117 		return (-1);
    118 	}
    119 	log_debug("socket is %s", path);
    120 
    121 retry:
    122 	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
    123 		return (-1);
    124 
    125 	log_debug("trying connect");
    126 	if (connect(fd, (struct sockaddr *)&sa, sizeof sa) == -1) {
    127 		log_debug("connect failed: %s", strerror(errno));
    128 		if (errno != ECONNREFUSED && errno != ENOENT)
    129 			goto failed;
    130 		if (flags & CLIENT_NOSTARTSERVER)
    131 			goto failed;
    132 		if (~flags & CLIENT_STARTSERVER)
    133 			goto failed;
    134 		close(fd);
    135 
    136 		if (!locked) {
    137 			xasprintf(&lockfile, "%s.lock", path);
    138 			if ((lockfd = client_get_lock(lockfile)) < 0) {
    139 				log_debug("didn't get lock (%d)", lockfd);
    140 
    141 				free(lockfile);
    142 				lockfile = NULL;
    143 
    144 				if (lockfd == -2)
    145 					goto retry;
    146 			}
    147 			log_debug("got lock (%d)", lockfd);
    148 
    149 			/*
    150 			 * Always retry at least once, even if we got the lock,
    151 			 * because another client could have taken the lock,
    152 			 * started the server and released the lock between our
    153 			 * connect() and flock().
    154 			 */
    155 			locked = 1;
    156 			goto retry;
    157 		}
    158 
    159 		if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) {
    160 			free(lockfile);
    161 			close(lockfd);
    162 			return (-1);
    163 		}
    164 		fd = server_start(client_proc, flags, base, lockfd, lockfile);
    165 	}
    166 
    167 	if (locked && lockfd >= 0) {
    168 		free(lockfile);
    169 		close(lockfd);
    170 	}
    171 	setblocking(fd, 0);
    172 	return (fd);
    173 
    174 failed:
    175 	if (locked) {
    176 		free(lockfile);
    177 		close(lockfd);
    178 	}
    179 	close(fd);
    180 	return (-1);
    181 }
    182 
    183 /* Get exit string from reason number. */
    184 const char *
    185 client_exit_message(void)
    186 {
    187 	static char msg[256];
    188 
    189 	switch (client_exitreason) {
    190 	case CLIENT_EXIT_NONE:
    191 		break;
    192 	case CLIENT_EXIT_DETACHED:
    193 		if (client_exitsession != NULL) {
    194 			xsnprintf(msg, sizeof msg, "detached "
    195 			    "(from session %s)", client_exitsession);
    196 			return (msg);
    197 		}
    198 		return ("detached");
    199 	case CLIENT_EXIT_DETACHED_HUP:
    200 		if (client_exitsession != NULL) {
    201 			xsnprintf(msg, sizeof msg, "detached and SIGHUP "
    202 			    "(from session %s)", client_exitsession);
    203 			return (msg);
    204 		}
    205 		return ("detached and SIGHUP");
    206 	case CLIENT_EXIT_LOST_TTY:
    207 		return ("lost tty");
    208 	case CLIENT_EXIT_TERMINATED:
    209 		return ("terminated");
    210 	case CLIENT_EXIT_LOST_SERVER:
    211 		return ("server exited unexpectedly");
    212 	case CLIENT_EXIT_EXITED:
    213 		return ("exited");
    214 	case CLIENT_EXIT_SERVER_EXITED:
    215 		return ("server exited");
    216 	case CLIENT_EXIT_MESSAGE_PROVIDED:
    217 		return (client_exitmessage);
    218 	}
    219 	return ("unknown reason");
    220 }
    221 
    222 /* Exit if all streams flushed. */
    223 static void
    224 client_exit(void)
    225 {
    226 	if (!file_write_left(&client_files))
    227 		proc_exit(client_proc);
    228 }
    229 
    230 /* Client main loop. */
    231 int
    232 client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
    233     int feat)
    234 {
    235 	struct cmd_parse_result	*pr;
    236 	struct msg_command	*data;
    237 	int			 fd, i;
    238 	const char		*ttynam, *termname, *cwd;
    239 	pid_t			 ppid;
    240 	enum msgtype		 msg;
    241 	struct termios		 tio, saved_tio;
    242 	size_t			 size, linesize = 0;
    243 	ssize_t			 linelen;
    244 	char			*line = NULL, **caps = NULL, *cause;
    245 	u_int			 ncaps = 0;
    246 	struct args_value	*values;
    247 
    248 	/* Set up the initial command. */
    249 	if (shell_command != NULL) {
    250 		msg = MSG_SHELL;
    251 		flags |= CLIENT_STARTSERVER;
    252 	} else if (argc == 0) {
    253 		msg = MSG_COMMAND;
    254 		flags |= CLIENT_STARTSERVER;
    255 	} else {
    256 		msg = MSG_COMMAND;
    257 
    258 		/*
    259 		 * It's annoying parsing the command string twice (in client
    260 		 * and later in server) but it is necessary to get the start
    261 		 * server flag.
    262 		 */
    263 		values = args_from_vector(argc, argv);
    264 		pr = cmd_parse_from_arguments(values, argc, NULL);
    265 		if (pr->status == CMD_PARSE_SUCCESS) {
    266 			if (cmd_list_any_have(pr->cmdlist, CMD_STARTSERVER))
    267 				flags |= CLIENT_STARTSERVER;
    268 			cmd_list_free(pr->cmdlist);
    269 		} else
    270 			free(pr->error);
    271 		args_free_values(values, argc);
    272 		free(values);
    273 	}
    274 
    275 	/* Create client process structure (starts logging). */
    276 	client_proc = proc_start("client");
    277 	proc_set_signals(client_proc, client_signal);
    278 
    279 	/* Save the flags. */
    280 	client_flags = flags;
    281 	log_debug("flags are %#llx", (unsigned long long)client_flags);
    282 
    283 	/* Initialize the client socket and start the server. */
    284 #ifdef HAVE_SYSTEMD
    285 	if (systemd_activated()) {
    286 		/* socket-based activation, do not even try to be a client. */
    287 		fd = server_start(client_proc, flags, base, 0, NULL);
    288 	} else
    289 #endif
    290 	fd = client_connect(base, socket_path, client_flags);
    291 	if (fd == -1) {
    292 		if (errno == ECONNREFUSED) {
    293 			fprintf(stderr, "no server running on %s\n",
    294 			    socket_path);
    295 		} else {
    296 			fprintf(stderr, "error connecting to %s (%s)\n",
    297 			    socket_path, strerror(errno));
    298 		}
    299 		return (1);
    300 	}
    301 	client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL);
    302 
    303 	/* Save these before pledge(). */
    304 	if ((cwd = find_cwd()) == NULL && (cwd = find_home()) == NULL)
    305 		cwd = "/";
    306 	if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
    307 		ttynam = "";
    308 	if ((termname = getenv("TERM")) == NULL)
    309 		termname = "";
    310 
    311 	/*
    312 	 * Drop privileges for client. "proc exec" is needed for -c and for
    313 	 * locking (which uses system(3)).
    314 	 *
    315 	 * "tty" is needed to restore termios(4) and also for some reason -CC
    316 	 * does not work properly without it (input is not recognised).
    317 	 *
    318 	 * "sendfd" is dropped later in client_dispatch_wait().
    319 	 */
    320 	if (pledge(
    321 	    "stdio rpath wpath cpath unix sendfd proc exec tty",
    322 	    NULL) != 0)
    323 		fatal("pledge failed");
    324 
    325 	/* Load terminfo entry if any. */
    326 	if (isatty(STDIN_FILENO) &&
    327 	    *termname != '\0' &&
    328 	    tty_term_read_list(termname, STDIN_FILENO, &caps, &ncaps,
    329 	    &cause) != 0) {
    330 		fprintf(stderr, "%s\n", cause);
    331 		free(cause);
    332 		return (1);
    333 	}
    334 
    335 	/* Free stuff that is not used in the client. */
    336 	if (ptm_fd != -1)
    337 		close(ptm_fd);
    338 	options_free(global_options);
    339 	options_free(global_s_options);
    340 	options_free(global_w_options);
    341 	environ_free(global_environ);
    342 
    343 	/* Set up control mode. */
    344 	if (client_flags & CLIENT_CONTROLCONTROL) {
    345 		if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
    346 			fprintf(stderr, "tcgetattr failed: %s\n",
    347 			    strerror(errno));
    348 			return (1);
    349 		}
    350 		cfmakeraw(&tio);
    351 		tio.c_iflag = ICRNL|IXANY;
    352 		tio.c_oflag = OPOST|ONLCR;
    353 #ifdef NOKERNINFO
    354 		tio.c_lflag = NOKERNINFO;
    355 #endif
    356 		tio.c_cflag = CREAD|CS8|HUPCL;
    357 		tio.c_cc[VMIN] = 1;
    358 		tio.c_cc[VTIME] = 0;
    359 		cfsetispeed(&tio, cfgetispeed(&saved_tio));
    360 		cfsetospeed(&tio, cfgetospeed(&saved_tio));
    361 		tcsetattr(STDIN_FILENO, TCSANOW, &tio);
    362 	}
    363 
    364 	/* Send identify messages. */
    365 	client_send_identify(ttynam, termname, caps, ncaps, cwd, feat);
    366 	tty_term_free_list(caps, ncaps);
    367 	proc_flush_peer(client_peer);
    368 
    369 	/* Send first command. */
    370 	if (msg == MSG_COMMAND) {
    371 		/* How big is the command? */
    372 		size = 0;
    373 		for (i = 0; i < argc; i++)
    374 			size += strlen(argv[i]) + 1;
    375 		if (size > MAX_IMSGSIZE - (sizeof *data)) {
    376 			fprintf(stderr, "command too long\n");
    377 			return (1);
    378 		}
    379 		data = xmalloc((sizeof *data) + size);
    380 
    381 		/* Prepare command for server. */
    382 		data->argc = argc;
    383 		if (cmd_pack_argv(argc, argv, (char *)(data + 1), size) != 0) {
    384 			fprintf(stderr, "command too long\n");
    385 			free(data);
    386 			return (1);
    387 		}
    388 		size += sizeof *data;
    389 
    390 		/* Send the command. */
    391 		if (proc_send(client_peer, msg, -1, data, size) != 0) {
    392 			fprintf(stderr, "failed to send command\n");
    393 			free(data);
    394 			return (1);
    395 		}
    396 		free(data);
    397 	} else if (msg == MSG_SHELL)
    398 		proc_send(client_peer, msg, -1, NULL, 0);
    399 
    400 	/* Start main loop. */
    401 	proc_loop(client_proc, NULL);
    402 
    403 	/* Run command if user requested exec, instead of exiting. */
    404 	if (client_exittype == MSG_EXEC) {
    405 		if (client_flags & CLIENT_CONTROLCONTROL)
    406 			tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
    407 		client_exec(client_execshell, client_execcmd);
    408 	}
    409 
    410 	/* Restore streams to blocking. */
    411 	setblocking(STDIN_FILENO, 1);
    412 	setblocking(STDOUT_FILENO, 1);
    413 	setblocking(STDERR_FILENO, 1);
    414 
    415 	/* Print the exit message, if any, and exit. */
    416 	if (client_attached) {
    417 		if (client_exitreason != CLIENT_EXIT_NONE)
    418 			printf("[%s]\n", client_exit_message());
    419 
    420 		ppid = getppid();
    421 		if (client_exittype == MSG_DETACHKILL && ppid > 1)
    422 			kill(ppid, SIGHUP);
    423 	} else if (client_flags & CLIENT_CONTROL) {
    424 		if (client_exitreason != CLIENT_EXIT_NONE)
    425 			printf("%%exit %s\n", client_exit_message());
    426 		else
    427 			printf("%%exit\n");
    428 		fflush(stdout);
    429 		if (client_flags & CLIENT_CONTROL_WAITEXIT) {
    430 			setvbuf(stdin, NULL, _IOLBF, 0);
    431 			for (;;) {
    432 				linelen = getline(&line, &linesize, stdin);
    433 				if (linelen <= 1)
    434 					break;
    435 			}
    436 			free(line);
    437 		}
    438 		if (client_flags & CLIENT_CONTROLCONTROL) {
    439 			printf("\033\\");
    440 			fflush(stdout);
    441 			tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
    442 		}
    443 	} else if (client_exitreason != CLIENT_EXIT_NONE)
    444 		fprintf(stderr, "%s\n", client_exit_message());
    445 	return (client_exitval);
    446 }
    447 
    448 /* Send identify messages to server. */
    449 static void
    450 client_send_identify(const char *ttynam, const char *termname, char **caps,
    451     u_int ncaps, const char *cwd, int feat)
    452 {
    453 	char	**ss;
    454 	size_t	  sslen;
    455 	int	  fd;
    456 	uint64_t  flags = client_flags;
    457 	pid_t	  pid;
    458 	u_int	  i;
    459 
    460 	proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &flags, sizeof flags);
    461 	proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags,
    462 	    sizeof client_flags);
    463 
    464 	proc_send(client_peer, MSG_IDENTIFY_TERM, -1, termname,
    465 	    strlen(termname) + 1);
    466 	proc_send(client_peer, MSG_IDENTIFY_FEATURES, -1, &feat, sizeof feat);
    467 
    468 	proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam,
    469 	    strlen(ttynam) + 1);
    470 	proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1);
    471 
    472 	for (i = 0; i < ncaps; i++) {
    473 		proc_send(client_peer, MSG_IDENTIFY_TERMINFO, -1,
    474 		    caps[i], strlen(caps[i]) + 1);
    475 	}
    476 
    477 	if ((fd = dup(STDIN_FILENO)) == -1)
    478 		fatal("dup failed");
    479 	proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
    480 	if ((fd = dup(STDOUT_FILENO)) == -1)
    481 		fatal("dup failed");
    482 	proc_send(client_peer, MSG_IDENTIFY_STDOUT, fd, NULL, 0);
    483 
    484 	pid = getpid();
    485 	proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
    486 
    487 	for (ss = environ; *ss != NULL; ss++) {
    488 		sslen = strlen(*ss) + 1;
    489 		if (sslen > MAX_IMSGSIZE - IMSG_HEADER_SIZE)
    490 			continue;
    491 		proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
    492 	}
    493 
    494 	proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
    495 }
    496 
    497 /* Run command in shell; used for -c. */
    498 static __dead void
    499 client_exec(const char *shell, const char *shellcmd)
    500 {
    501 	char	*argv0;
    502 
    503 	log_debug("shell %s, command %s", shell, shellcmd);
    504 	argv0 = shell_argv0(shell, !!(client_flags & CLIENT_LOGIN));
    505 	setenv("SHELL", shell, 1);
    506 
    507 	proc_clear_signals(client_proc, 1);
    508 
    509 	setblocking(STDIN_FILENO, 1);
    510 	setblocking(STDOUT_FILENO, 1);
    511 	setblocking(STDERR_FILENO, 1);
    512 	closefrom(STDERR_FILENO + 1);
    513 
    514 	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
    515 	fatal("execl failed");
    516 }
    517 
    518 /* Callback to handle signals in the client. */
    519 static void
    520 client_signal(int sig)
    521 {
    522 	struct sigaction sigact;
    523 	int		 status;
    524 	pid_t		 pid;
    525 
    526 	log_debug("%s: %s", __func__, strsignal(sig));
    527 	if (sig == SIGCHLD) {
    528 		for (;;) {
    529 			pid = waitpid(WAIT_ANY, &status, WNOHANG);
    530 			if (pid == 0)
    531 				break;
    532 			if (pid == -1) {
    533 				if (errno == ECHILD)
    534 					break;
    535 				log_debug("waitpid failed: %s",
    536 				    strerror(errno));
    537 			}
    538 		}
    539 	} else if (!client_attached) {
    540 		if (sig == SIGTERM || sig == SIGHUP)
    541 			proc_exit(client_proc);
    542 	} else {
    543 		switch (sig) {
    544 		case SIGHUP:
    545 			client_exitreason = CLIENT_EXIT_LOST_TTY;
    546 			client_exitval = 1;
    547 			proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    548 			break;
    549 		case SIGTERM:
    550 			if (!client_suspended)
    551 				client_exitreason = CLIENT_EXIT_TERMINATED;
    552 			client_exitval = 1;
    553 			proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    554 			break;
    555 		case SIGWINCH:
    556 			proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
    557 			break;
    558 		case SIGCONT:
    559 			memset(&sigact, 0, sizeof sigact);
    560 			sigemptyset(&sigact.sa_mask);
    561 			sigact.sa_flags = SA_RESTART;
    562 			sigact.sa_handler = SIG_IGN;
    563 			if (sigaction(SIGTSTP, &sigact, NULL) != 0)
    564 				fatal("sigaction failed");
    565 			proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0);
    566 			client_suspended = 0;
    567 			break;
    568 		}
    569 	}
    570 }
    571 
    572 /* Callback for file write error or close. */
    573 static void
    574 client_file_check_cb(__unused struct client *c, __unused const char *path,
    575     __unused int error, __unused int closed, __unused struct evbuffer *buffer,
    576     __unused void *data)
    577 {
    578 	if (client_exitflag)
    579 		client_exit();
    580 }
    581 
    582 /* Callback for client read events. */
    583 static void
    584 client_dispatch(struct imsg *imsg, __unused void *arg)
    585 {
    586 	if (imsg == NULL) {
    587 		if (!client_exitflag) {
    588 			client_exitreason = CLIENT_EXIT_LOST_SERVER;
    589 			client_exitval = 1;
    590 		}
    591 		proc_exit(client_proc);
    592 		return;
    593 	}
    594 
    595 	if (client_attached)
    596 		client_dispatch_attached(imsg);
    597 	else
    598 		client_dispatch_wait(imsg);
    599 }
    600 
    601 /* Process an exit message. */
    602 static void
    603 client_dispatch_exit_message(char *data, size_t datalen)
    604 {
    605 	int	retval;
    606 
    607 	if (datalen < sizeof retval && datalen != 0)
    608 		fatalx("bad MSG_EXIT size");
    609 
    610 	if (datalen >= sizeof retval) {
    611 		memcpy(&retval, data, sizeof retval);
    612 		client_exitval = retval;
    613 	}
    614 
    615 	if (datalen > sizeof retval) {
    616 		datalen -= sizeof retval;
    617 		data += sizeof retval;
    618 
    619 		client_exitmessage = xmalloc(datalen);
    620 		memcpy(client_exitmessage, data, datalen);
    621 		client_exitmessage[datalen - 1] = '\0';
    622 
    623 		client_exitreason = CLIENT_EXIT_MESSAGE_PROVIDED;
    624 	}
    625 }
    626 
    627 /* Dispatch imsgs when in wait state (before MSG_READY). */
    628 static void
    629 client_dispatch_wait(struct imsg *imsg)
    630 {
    631 	char		*data;
    632 	ssize_t		 datalen;
    633 	static int	 pledge_applied;
    634 
    635 	/*
    636 	 * "sendfd" is no longer required once all of the identify messages
    637 	 * have been sent. We know the server won't send us anything until that
    638 	 * point (because we don't ask it to), so we can drop "sendfd" once we
    639 	 * get the first message from the server.
    640 	 */
    641 	if (!pledge_applied) {
    642 		if (pledge(
    643 		    "stdio rpath wpath cpath unix proc exec tty",
    644 		    NULL) != 0)
    645 			fatal("pledge failed");
    646 		pledge_applied = 1;
    647 	}
    648 
    649 	data = imsg->data;
    650 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
    651 
    652 	switch (imsg->hdr.type) {
    653 	case MSG_EXIT:
    654 	case MSG_SHUTDOWN:
    655 		client_dispatch_exit_message(data, datalen);
    656 		client_exitflag = 1;
    657 		client_exit();
    658 		break;
    659 	case MSG_READY:
    660 		if (datalen != 0)
    661 			fatalx("bad MSG_READY size");
    662 
    663 		client_attached = 1;
    664 		proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
    665 		break;
    666 	case MSG_VERSION:
    667 		if (datalen != 0)
    668 			fatalx("bad MSG_VERSION size");
    669 
    670 		fprintf(stderr, "protocol version mismatch "
    671 		    "(client %d, server %u)\n", PROTOCOL_VERSION,
    672 		    imsg->hdr.peerid & 0xff);
    673 		client_exitval = 1;
    674 		proc_exit(client_proc);
    675 		break;
    676 	case MSG_FLAGS:
    677 		if (datalen != sizeof client_flags)
    678 			fatalx("bad MSG_FLAGS string");
    679 
    680 		memcpy(&client_flags, data, sizeof client_flags);
    681 		log_debug("new flags are %#llx",
    682 		    (unsigned long long)client_flags);
    683 		break;
    684 	case MSG_SHELL:
    685 		if (datalen == 0 || data[datalen - 1] != '\0')
    686 			fatalx("bad MSG_SHELL string");
    687 
    688 		client_exec(data, shell_command);
    689 		/* NOTREACHED */
    690 	case MSG_DETACH:
    691 	case MSG_DETACHKILL:
    692 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    693 		break;
    694 	case MSG_EXITED:
    695 		proc_exit(client_proc);
    696 		break;
    697 	case MSG_READ_OPEN:
    698 		file_read_open(&client_files, client_peer, imsg, 1,
    699 		    !(client_flags & CLIENT_CONTROL), client_file_check_cb,
    700 		    NULL);
    701 		break;
    702 	case MSG_READ_CANCEL:
    703 		file_read_cancel(&client_files, imsg);
    704 		break;
    705 	case MSG_WRITE_OPEN:
    706 		file_write_open(&client_files, client_peer, imsg, 1,
    707 		    !(client_flags & CLIENT_CONTROL), client_file_check_cb,
    708 		    NULL);
    709 		break;
    710 	case MSG_WRITE:
    711 		file_write_data(&client_files, imsg);
    712 		break;
    713 	case MSG_WRITE_CLOSE:
    714 		file_write_close(&client_files, imsg);
    715 		break;
    716 	case MSG_OLDSTDERR:
    717 	case MSG_OLDSTDIN:
    718 	case MSG_OLDSTDOUT:
    719 		fprintf(stderr, "server version is too old for client\n");
    720 		proc_exit(client_proc);
    721 		break;
    722 	}
    723 }
    724 
    725 /* Dispatch imsgs in attached state (after MSG_READY). */
    726 static void
    727 client_dispatch_attached(struct imsg *imsg)
    728 {
    729 	struct sigaction	 sigact;
    730 	char			*data;
    731 	ssize_t			 datalen;
    732 
    733 	data = imsg->data;
    734 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
    735 
    736 	switch (imsg->hdr.type) {
    737 	case MSG_FLAGS:
    738 		if (datalen != sizeof client_flags)
    739 			fatalx("bad MSG_FLAGS string");
    740 
    741 		memcpy(&client_flags, data, sizeof client_flags);
    742 		log_debug("new flags are %#llx",
    743 		    (unsigned long long)client_flags);
    744 		break;
    745 	case MSG_DETACH:
    746 	case MSG_DETACHKILL:
    747 		if (datalen == 0 || data[datalen - 1] != '\0')
    748 			fatalx("bad MSG_DETACH string");
    749 
    750 		client_exitsession = xstrdup(data);
    751 		client_exittype = imsg->hdr.type;
    752 		if (imsg->hdr.type == MSG_DETACHKILL)
    753 			client_exitreason = CLIENT_EXIT_DETACHED_HUP;
    754 		else
    755 			client_exitreason = CLIENT_EXIT_DETACHED;
    756 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    757 		break;
    758 	case MSG_EXEC:
    759 		if (datalen == 0 || data[datalen - 1] != '\0' ||
    760 		    strlen(data) + 1 == (size_t)datalen)
    761 			fatalx("bad MSG_EXEC string");
    762 		client_execcmd = xstrdup(data);
    763 		client_execshell = xstrdup(data + strlen(data) + 1);
    764 
    765 		client_exittype = imsg->hdr.type;
    766 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    767 		break;
    768 	case MSG_EXIT:
    769 		client_dispatch_exit_message(data, datalen);
    770 		if (client_exitreason == CLIENT_EXIT_NONE)
    771 			client_exitreason = CLIENT_EXIT_EXITED;
    772 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    773 		break;
    774 	case MSG_EXITED:
    775 		if (datalen != 0)
    776 			fatalx("bad MSG_EXITED size");
    777 
    778 		proc_exit(client_proc);
    779 		break;
    780 	case MSG_SHUTDOWN:
    781 		if (datalen != 0)
    782 			fatalx("bad MSG_SHUTDOWN size");
    783 
    784 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
    785 		client_exitreason = CLIENT_EXIT_SERVER_EXITED;
    786 		client_exitval = 1;
    787 		break;
    788 	case MSG_SUSPEND:
    789 		if (datalen != 0)
    790 			fatalx("bad MSG_SUSPEND size");
    791 
    792 		memset(&sigact, 0, sizeof sigact);
    793 		sigemptyset(&sigact.sa_mask);
    794 		sigact.sa_flags = SA_RESTART;
    795 		sigact.sa_handler = SIG_DFL;
    796 		if (sigaction(SIGTSTP, &sigact, NULL) != 0)
    797 			fatal("sigaction failed");
    798 		client_suspended = 1;
    799 		kill(getpid(), SIGTSTP);
    800 		break;
    801 	case MSG_LOCK:
    802 		if (datalen == 0 || data[datalen - 1] != '\0')
    803 			fatalx("bad MSG_LOCK string");
    804 
    805 		system(data);
    806 		proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0);
    807 		break;
    808 	}
    809 }
    810