xref: /openbsd-src/usr.bin/tmux/client.c (revision 46035553bfdd96e63c94e32da0210227ec2e3cf1)
1 /* $OpenBSD: client.c,v 1.150 2020/10/30 18:54:23 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <sys/uio.h>
22 #include <sys/un.h>
23 #include <sys/wait.h>
24 
25 #include <errno.h>
26 #include <event.h>
27 #include <fcntl.h>
28 #include <imsg.h>
29 #include <signal.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 
34 #include "tmux.h"
35 
36 static struct tmuxproc	*client_proc;
37 static struct tmuxpeer	*client_peer;
38 static uint64_t		 client_flags;
39 static int		 client_suspended;
40 static enum {
41 	CLIENT_EXIT_NONE,
42 	CLIENT_EXIT_DETACHED,
43 	CLIENT_EXIT_DETACHED_HUP,
44 	CLIENT_EXIT_LOST_TTY,
45 	CLIENT_EXIT_TERMINATED,
46 	CLIENT_EXIT_LOST_SERVER,
47 	CLIENT_EXIT_EXITED,
48 	CLIENT_EXIT_SERVER_EXITED,
49 	CLIENT_EXIT_MESSAGE_PROVIDED
50 } client_exitreason = CLIENT_EXIT_NONE;
51 static int		 client_exitflag;
52 static int		 client_exitval;
53 static enum msgtype	 client_exittype;
54 static const char	*client_exitsession;
55 static char		*client_exitmessage;
56 static const char	*client_execshell;
57 static const char	*client_execcmd;
58 static int		 client_attached;
59 static struct client_files client_files = RB_INITIALIZER(&client_files);
60 
61 static __dead void	 client_exec(const char *,const char *);
62 static int		 client_get_lock(char *);
63 static int		 client_connect(struct event_base *, const char *,
64 			     uint64_t);
65 static void		 client_send_identify(const char *, 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_STARTSERVER)
131 			goto failed;
132 		close(fd);
133 
134 		if (!locked) {
135 			xasprintf(&lockfile, "%s.lock", path);
136 			if ((lockfd = client_get_lock(lockfile)) < 0) {
137 				log_debug("didn't get lock (%d)", lockfd);
138 
139 				free(lockfile);
140 				lockfile = NULL;
141 
142 				if (lockfd == -2)
143 					goto retry;
144 			}
145 			log_debug("got lock (%d)", lockfd);
146 
147 			/*
148 			 * Always retry at least once, even if we got the lock,
149 			 * because another client could have taken the lock,
150 			 * started the server and released the lock between our
151 			 * connect() and flock().
152 			 */
153 			locked = 1;
154 			goto retry;
155 		}
156 
157 		if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) {
158 			free(lockfile);
159 			close(lockfd);
160 			return (-1);
161 		}
162 		fd = server_start(client_proc, flags, base, lockfd, lockfile);
163 	}
164 
165 	if (locked && lockfd >= 0) {
166 		free(lockfile);
167 		close(lockfd);
168 	}
169 	setblocking(fd, 0);
170 	return (fd);
171 
172 failed:
173 	if (locked) {
174 		free(lockfile);
175 		close(lockfd);
176 	}
177 	close(fd);
178 	return (-1);
179 }
180 
181 /* Get exit string from reason number. */
182 const char *
183 client_exit_message(void)
184 {
185 	static char msg[256];
186 
187 	switch (client_exitreason) {
188 	case CLIENT_EXIT_NONE:
189 		break;
190 	case CLIENT_EXIT_DETACHED:
191 		if (client_exitsession != NULL) {
192 			xsnprintf(msg, sizeof msg, "detached "
193 			    "(from session %s)", client_exitsession);
194 			return (msg);
195 		}
196 		return ("detached");
197 	case CLIENT_EXIT_DETACHED_HUP:
198 		if (client_exitsession != NULL) {
199 			xsnprintf(msg, sizeof msg, "detached and SIGHUP "
200 			    "(from session %s)", client_exitsession);
201 			return (msg);
202 		}
203 		return ("detached and SIGHUP");
204 	case CLIENT_EXIT_LOST_TTY:
205 		return ("lost tty");
206 	case CLIENT_EXIT_TERMINATED:
207 		return ("terminated");
208 	case CLIENT_EXIT_LOST_SERVER:
209 		return ("server exited unexpectedly");
210 	case CLIENT_EXIT_EXITED:
211 		return ("exited");
212 	case CLIENT_EXIT_SERVER_EXITED:
213 		return ("server exited");
214 	case CLIENT_EXIT_MESSAGE_PROVIDED:
215 		return (client_exitmessage);
216 	}
217 	return ("unknown reason");
218 }
219 
220 /* Exit if all streams flushed. */
221 static void
222 client_exit(void)
223 {
224 	struct client_file	*cf;
225 	size_t			 left;
226 	int			 waiting = 0;
227 
228 	RB_FOREACH (cf, client_files, &client_files) {
229 		if (cf->event == NULL)
230 			continue;
231 		left = EVBUFFER_LENGTH(cf->event->output);
232 		if (left != 0) {
233 			waiting++;
234 			log_debug("file %u %zu bytes left", cf->stream, left);
235 		}
236 	}
237 	if (waiting == 0)
238 		proc_exit(client_proc);
239 }
240 
241 /* Client main loop. */
242 int
243 client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
244     int feat)
245 {
246 	struct cmd_parse_result	*pr;
247 	struct msg_command	*data;
248 	int			 fd, i;
249 	const char		*ttynam, *cwd;
250 	pid_t			 ppid;
251 	enum msgtype		 msg;
252 	struct termios		 tio, saved_tio;
253 	size_t			 size, linesize = 0;
254 	ssize_t			 linelen;
255 	char			*line = NULL;
256 
257 	/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
258 	signal(SIGCHLD, SIG_IGN);
259 
260 	/* Set up the initial command. */
261 	if (shell_command != NULL) {
262 		msg = MSG_SHELL;
263 		flags |= CLIENT_STARTSERVER;
264 	} else if (argc == 0) {
265 		msg = MSG_COMMAND;
266 		flags |= CLIENT_STARTSERVER;
267 	} else {
268 		msg = MSG_COMMAND;
269 
270 		/*
271 		 * It sucks parsing the command string twice (in client and
272 		 * later in server) but it is necessary to get the start server
273 		 * flag.
274 		 */
275 		pr = cmd_parse_from_arguments(argc, argv, NULL);
276 		if (pr->status == CMD_PARSE_SUCCESS) {
277 			if (cmd_list_any_have(pr->cmdlist, CMD_STARTSERVER))
278 				flags |= CLIENT_STARTSERVER;
279 			cmd_list_free(pr->cmdlist);
280 		} else
281 			free(pr->error);
282 	}
283 
284 	/* Create client process structure (starts logging). */
285 	client_proc = proc_start("client");
286 	proc_set_signals(client_proc, client_signal);
287 
288 	/* Save the flags. */
289 	client_flags = flags;
290 	log_debug("flags are %#llx", (unsigned long long)client_flags);
291 
292 	/* Initialize the client socket and start the server. */
293 	fd = client_connect(base, socket_path, client_flags);
294 	if (fd == -1) {
295 		if (errno == ECONNREFUSED) {
296 			fprintf(stderr, "no server running on %s\n",
297 			    socket_path);
298 		} else {
299 			fprintf(stderr, "error connecting to %s (%s)\n",
300 			    socket_path, strerror(errno));
301 		}
302 		return (1);
303 	}
304 	client_peer = proc_add_peer(client_proc, fd, client_dispatch, NULL);
305 
306 	/* Save these before pledge(). */
307 	if ((cwd = find_cwd()) == NULL && (cwd = find_home()) == NULL)
308 		cwd = "/";
309 	if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
310 		ttynam = "";
311 
312 	/*
313 	 * Drop privileges for client. "proc exec" is needed for -c and for
314 	 * locking (which uses system(3)).
315 	 *
316 	 * "tty" is needed to restore termios(4) and also for some reason -CC
317 	 * does not work properly without it (input is not recognised).
318 	 *
319 	 * "sendfd" is dropped later in client_dispatch_wait().
320 	 */
321 	if (pledge(
322 	    "stdio rpath wpath cpath unix sendfd proc exec tty",
323 	    NULL) != 0)
324 		fatal("pledge failed");
325 
326 	/* Free stuff that is not used in the client. */
327 	if (ptm_fd != -1)
328 		close(ptm_fd);
329 	options_free(global_options);
330 	options_free(global_s_options);
331 	options_free(global_w_options);
332 	environ_free(global_environ);
333 
334 	/* Set up control mode. */
335 	if (client_flags & CLIENT_CONTROLCONTROL) {
336 		if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
337 			fprintf(stderr, "tcgetattr failed: %s\n",
338 			    strerror(errno));
339 			return (1);
340 		}
341 		cfmakeraw(&tio);
342 		tio.c_iflag = ICRNL|IXANY;
343 		tio.c_oflag = OPOST|ONLCR;
344 		tio.c_lflag = NOKERNINFO;
345 		tio.c_cflag = CREAD|CS8|HUPCL;
346 		tio.c_cc[VMIN] = 1;
347 		tio.c_cc[VTIME] = 0;
348 		cfsetispeed(&tio, cfgetispeed(&saved_tio));
349 		cfsetospeed(&tio, cfgetospeed(&saved_tio));
350 		tcsetattr(STDIN_FILENO, TCSANOW, &tio);
351 	}
352 
353 	/* Send identify messages. */
354 	client_send_identify(ttynam, cwd, feat);
355 
356 	/* Send first command. */
357 	if (msg == MSG_COMMAND) {
358 		/* How big is the command? */
359 		size = 0;
360 		for (i = 0; i < argc; i++)
361 			size += strlen(argv[i]) + 1;
362 		if (size > MAX_IMSGSIZE - (sizeof *data)) {
363 			fprintf(stderr, "command too long\n");
364 			return (1);
365 		}
366 		data = xmalloc((sizeof *data) + size);
367 
368 		/* Prepare command for server. */
369 		data->argc = argc;
370 		if (cmd_pack_argv(argc, argv, (char *)(data + 1), size) != 0) {
371 			fprintf(stderr, "command too long\n");
372 			free(data);
373 			return (1);
374 		}
375 		size += sizeof *data;
376 
377 		/* Send the command. */
378 		if (proc_send(client_peer, msg, -1, data, size) != 0) {
379 			fprintf(stderr, "failed to send command\n");
380 			free(data);
381 			return (1);
382 		}
383 		free(data);
384 	} else if (msg == MSG_SHELL)
385 		proc_send(client_peer, msg, -1, NULL, 0);
386 
387 	/* Start main loop. */
388 	proc_loop(client_proc, NULL);
389 
390 	/* Run command if user requested exec, instead of exiting. */
391 	if (client_exittype == MSG_EXEC) {
392 		if (client_flags & CLIENT_CONTROLCONTROL)
393 			tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
394 		client_exec(client_execshell, client_execcmd);
395 	}
396 
397 	/* Restore streams to blocking. */
398 	setblocking(STDIN_FILENO, 1);
399 	setblocking(STDOUT_FILENO, 1);
400 	setblocking(STDERR_FILENO, 1);
401 
402 	/* Print the exit message, if any, and exit. */
403 	if (client_attached) {
404 		if (client_exitreason != CLIENT_EXIT_NONE)
405 			printf("[%s]\n", client_exit_message());
406 
407 		ppid = getppid();
408 		if (client_exittype == MSG_DETACHKILL && ppid > 1)
409 			kill(ppid, SIGHUP);
410 	} else if (client_flags & CLIENT_CONTROL) {
411 		if (client_exitreason != CLIENT_EXIT_NONE)
412 			printf("%%exit %s\n", client_exit_message());
413 		else
414 			printf("%%exit\n");
415 		fflush(stdout);
416 		if (client_flags & CLIENT_CONTROL_WAITEXIT) {
417 			setvbuf(stdin, NULL, _IOLBF, 0);
418 			for (;;) {
419 				linelen = getline(&line, &linesize, stdin);
420 				if (linelen <= 1)
421 					break;
422 			}
423 			free(line);
424 		}
425 		if (client_flags & CLIENT_CONTROLCONTROL) {
426 			printf("\033\\");
427 			fflush(stdout);
428 			tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
429 		}
430 	} else if (client_exitreason != CLIENT_EXIT_NONE)
431 		fprintf(stderr, "%s\n", client_exit_message());
432 	return (client_exitval);
433 }
434 
435 /* Send identify messages to server. */
436 static void
437 client_send_identify(const char *ttynam, const char *cwd, int feat)
438 {
439 	const char	 *s;
440 	char		**ss;
441 	size_t		  sslen;
442 	int		  fd, flags = client_flags;
443 	pid_t		  pid;
444 
445 	proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
446 	proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags,
447 	    sizeof client_flags);
448 
449 	if ((s = getenv("TERM")) == NULL)
450 		s = "";
451 	proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
452 	proc_send(client_peer, MSG_IDENTIFY_FEATURES, -1, &feat, sizeof feat);
453 
454 	proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam,
455 	    strlen(ttynam) + 1);
456 	proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1);
457 
458 	if ((fd = dup(STDIN_FILENO)) == -1)
459 		fatal("dup failed");
460 	proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
461 	if ((fd = dup(STDOUT_FILENO)) == -1)
462 		fatal("dup failed");
463 	proc_send(client_peer, MSG_IDENTIFY_STDOUT, fd, NULL, 0);
464 
465 	pid = getpid();
466 	proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
467 
468 	for (ss = environ; *ss != NULL; ss++) {
469 		sslen = strlen(*ss) + 1;
470 		if (sslen > MAX_IMSGSIZE - IMSG_HEADER_SIZE)
471 			continue;
472 		proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
473 	}
474 
475 	proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
476 }
477 
478 /* File write error callback. */
479 static void
480 client_write_error_callback(__unused struct bufferevent *bev,
481     __unused short what, void *arg)
482 {
483 	struct client_file	*cf = arg;
484 
485 	log_debug("write error file %d", cf->stream);
486 
487 	bufferevent_free(cf->event);
488 	cf->event = NULL;
489 
490 	close(cf->fd);
491 	cf->fd = -1;
492 
493 	if (client_exitflag)
494 		client_exit();
495 }
496 
497 /* File write callback. */
498 static void
499 client_write_callback(__unused struct bufferevent *bev, void *arg)
500 {
501 	struct client_file	*cf = arg;
502 
503 	if (cf->closed && EVBUFFER_LENGTH(cf->event->output) == 0) {
504 		bufferevent_free(cf->event);
505 		close(cf->fd);
506 		RB_REMOVE(client_files, &client_files, cf);
507 		file_free(cf);
508 	}
509 
510 	if (client_exitflag)
511 		client_exit();
512 }
513 
514 /* Open write file. */
515 static void
516 client_write_open(void *data, size_t datalen)
517 {
518 	struct msg_write_open	*msg = data;
519 	const char		*path;
520 	struct msg_write_ready	 reply;
521 	struct client_file	 find, *cf;
522 	const int		 flags = O_NONBLOCK|O_WRONLY|O_CREAT;
523 	int			 error = 0;
524 
525 	if (datalen < sizeof *msg)
526 		fatalx("bad MSG_WRITE_OPEN size");
527 	if (datalen == sizeof *msg)
528 		path = "-";
529 	else
530 		path = (const char *)(msg + 1);
531 	log_debug("open write file %d %s", msg->stream, path);
532 
533 	find.stream = msg->stream;
534 	if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) {
535 		cf = file_create(NULL, msg->stream, NULL, NULL);
536 		RB_INSERT(client_files, &client_files, cf);
537 	} else {
538 		error = EBADF;
539 		goto reply;
540 	}
541 	if (cf->closed) {
542 		error = EBADF;
543 		goto reply;
544 	}
545 
546 	cf->fd = -1;
547 	if (msg->fd == -1)
548 		cf->fd = open(path, msg->flags|flags, 0644);
549 	else {
550 		if (msg->fd != STDOUT_FILENO && msg->fd != STDERR_FILENO)
551 			errno = EBADF;
552 		else {
553 			cf->fd = dup(msg->fd);
554 			if (~client_flags & CLIENT_CONTROL)
555 				close(msg->fd); /* can only be used once */
556 		}
557 	}
558 	if (cf->fd == -1) {
559 		error = errno;
560 		goto reply;
561 	}
562 
563 	cf->event = bufferevent_new(cf->fd, NULL, client_write_callback,
564 	    client_write_error_callback, cf);
565 	bufferevent_enable(cf->event, EV_WRITE);
566 	goto reply;
567 
568 reply:
569 	reply.stream = msg->stream;
570 	reply.error = error;
571 	proc_send(client_peer, MSG_WRITE_READY, -1, &reply, sizeof reply);
572 }
573 
574 /* Write to client file. */
575 static void
576 client_write_data(void *data, size_t datalen)
577 {
578 	struct msg_write_data	*msg = data;
579 	struct client_file	 find, *cf;
580 	size_t			 size = datalen - sizeof *msg;
581 
582 	if (datalen < sizeof *msg)
583 		fatalx("bad MSG_WRITE size");
584 	find.stream = msg->stream;
585 	if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
586 		fatalx("unknown stream number");
587 	log_debug("write %zu to file %d", size, cf->stream);
588 
589 	if (cf->event != NULL)
590 		bufferevent_write(cf->event, msg + 1, size);
591 }
592 
593 /* Close client file. */
594 static void
595 client_write_close(void *data, size_t datalen)
596 {
597 	struct msg_write_close	*msg = data;
598 	struct client_file	 find, *cf;
599 
600 	if (datalen != sizeof *msg)
601 		fatalx("bad MSG_WRITE_CLOSE size");
602 	find.stream = msg->stream;
603 	if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL)
604 		fatalx("unknown stream number");
605 	log_debug("close file %d", cf->stream);
606 
607 	if (cf->event == NULL || EVBUFFER_LENGTH(cf->event->output) == 0) {
608 		if (cf->event != NULL)
609 			bufferevent_free(cf->event);
610 		if (cf->fd != -1)
611 			close(cf->fd);
612 		RB_REMOVE(client_files, &client_files, cf);
613 		file_free(cf);
614 	}
615 }
616 
617 /* File read callback. */
618 static void
619 client_read_callback(__unused struct bufferevent *bev, void *arg)
620 {
621 	struct client_file	*cf = arg;
622 	void			*bdata;
623 	size_t			 bsize;
624 	struct msg_read_data	*msg;
625 	size_t			 msglen;
626 
627 	msg = xmalloc(sizeof *msg);
628 	for (;;) {
629 		bdata = EVBUFFER_DATA(cf->event->input);
630 		bsize = EVBUFFER_LENGTH(cf->event->input);
631 
632 		if (bsize == 0)
633 			break;
634 		if (bsize > MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg)
635 			bsize = MAX_IMSGSIZE - IMSG_HEADER_SIZE - sizeof *msg;
636 		log_debug("read %zu from file %d", bsize, cf->stream);
637 
638 		msglen = (sizeof *msg) + bsize;
639 		msg = xrealloc(msg, msglen);
640 		msg->stream = cf->stream;
641 		memcpy(msg + 1, bdata, bsize);
642 		proc_send(client_peer, MSG_READ, -1, msg, msglen);
643 
644 		evbuffer_drain(cf->event->input, bsize);
645 	}
646 	free(msg);
647 }
648 
649 /* File read error callback. */
650 static void
651 client_read_error_callback(__unused struct bufferevent *bev,
652     __unused short what, void *arg)
653 {
654 	struct client_file	*cf = arg;
655 	struct msg_read_done	 msg;
656 
657 	log_debug("read error file %d", cf->stream);
658 
659 	msg.stream = cf->stream;
660 	msg.error = 0;
661 	proc_send(client_peer, MSG_READ_DONE, -1, &msg, sizeof msg);
662 
663 	bufferevent_free(cf->event);
664 	close(cf->fd);
665 	RB_REMOVE(client_files, &client_files, cf);
666 	file_free(cf);
667 }
668 
669 /* Open read file. */
670 static void
671 client_read_open(void *data, size_t datalen)
672 {
673 	struct msg_read_open	*msg = data;
674 	const char		*path;
675 	struct msg_read_done	 reply;
676 	struct client_file	 find, *cf;
677 	const int		 flags = O_NONBLOCK|O_RDONLY;
678 	int			 error;
679 
680 	if (datalen < sizeof *msg)
681 		fatalx("bad MSG_READ_OPEN size");
682 	if (datalen == sizeof *msg)
683 		path = "-";
684 	else
685 		path = (const char *)(msg + 1);
686 	log_debug("open read file %d %s", msg->stream, path);
687 
688 	find.stream = msg->stream;
689 	if ((cf = RB_FIND(client_files, &client_files, &find)) == NULL) {
690 		cf = file_create(NULL, msg->stream, NULL, NULL);
691 		RB_INSERT(client_files, &client_files, cf);
692 	} else {
693 		error = EBADF;
694 		goto reply;
695 	}
696 	if (cf->closed) {
697 		error = EBADF;
698 		goto reply;
699 	}
700 
701 	cf->fd = -1;
702 	if (msg->fd == -1)
703 		cf->fd = open(path, flags);
704 	else {
705 		if (msg->fd != STDIN_FILENO)
706 			errno = EBADF;
707 		else {
708 			cf->fd = dup(msg->fd);
709 			if (~client_flags & CLIENT_CONTROL)
710 				close(msg->fd); /* can only be used once */
711 		}
712 	}
713 	if (cf->fd == -1) {
714 		error = errno;
715 		goto reply;
716 	}
717 
718 	cf->event = bufferevent_new(cf->fd, client_read_callback, NULL,
719 	    client_read_error_callback, cf);
720 	bufferevent_enable(cf->event, EV_READ);
721 	return;
722 
723 reply:
724 	reply.stream = msg->stream;
725 	reply.error = error;
726 	proc_send(client_peer, MSG_READ_DONE, -1, &reply, sizeof reply);
727 }
728 
729 /* Run command in shell; used for -c. */
730 static __dead void
731 client_exec(const char *shell, const char *shellcmd)
732 {
733 	const char	*name, *ptr;
734 	char		*argv0;
735 
736 	log_debug("shell %s, command %s", shell, shellcmd);
737 
738 	ptr = strrchr(shell, '/');
739 	if (ptr != NULL && *(ptr + 1) != '\0')
740 		name = ptr + 1;
741 	else
742 		name = shell;
743 	if (client_flags & CLIENT_LOGIN)
744 		xasprintf(&argv0, "-%s", name);
745 	else
746 		xasprintf(&argv0, "%s", name);
747 	setenv("SHELL", shell, 1);
748 
749 	proc_clear_signals(client_proc, 1);
750 
751 	setblocking(STDIN_FILENO, 1);
752 	setblocking(STDOUT_FILENO, 1);
753 	setblocking(STDERR_FILENO, 1);
754 	closefrom(STDERR_FILENO + 1);
755 
756 	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
757 	fatal("execl failed");
758 }
759 
760 /* Callback to handle signals in the client. */
761 static void
762 client_signal(int sig)
763 {
764 	struct sigaction sigact;
765 	int		 status;
766 
767 	log_debug("%s: %s", __func__, strsignal(sig));
768 	if (sig == SIGCHLD)
769 		waitpid(WAIT_ANY, &status, WNOHANG);
770 	else if (!client_attached) {
771 		if (sig == SIGTERM)
772 			proc_exit(client_proc);
773 	} else {
774 		switch (sig) {
775 		case SIGHUP:
776 			client_exitreason = CLIENT_EXIT_LOST_TTY;
777 			client_exitval = 1;
778 			proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
779 			break;
780 		case SIGTERM:
781 			if (!client_suspended)
782 				client_exitreason = CLIENT_EXIT_TERMINATED;
783 			client_exitval = 1;
784 			proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
785 			break;
786 		case SIGWINCH:
787 			proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
788 			break;
789 		case SIGCONT:
790 			memset(&sigact, 0, sizeof sigact);
791 			sigemptyset(&sigact.sa_mask);
792 			sigact.sa_flags = SA_RESTART;
793 			sigact.sa_handler = SIG_IGN;
794 			if (sigaction(SIGTSTP, &sigact, NULL) != 0)
795 				fatal("sigaction failed");
796 			proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0);
797 			client_suspended = 0;
798 			break;
799 		}
800 	}
801 }
802 
803 /* Callback for client read events. */
804 static void
805 client_dispatch(struct imsg *imsg, __unused void *arg)
806 {
807 	if (imsg == NULL) {
808 		client_exitreason = CLIENT_EXIT_LOST_SERVER;
809 		client_exitval = 1;
810 		proc_exit(client_proc);
811 		return;
812 	}
813 
814 	if (client_attached)
815 		client_dispatch_attached(imsg);
816 	else
817 		client_dispatch_wait(imsg);
818 }
819 
820 /* Process an exit message. */
821 static void
822 client_dispatch_exit_message(char *data, size_t datalen)
823 {
824 	int	retval;
825 
826 	if (datalen < sizeof retval && datalen != 0)
827 		fatalx("bad MSG_EXIT size");
828 
829 	if (datalen >= sizeof retval) {
830 		memcpy(&retval, data, sizeof retval);
831 		client_exitval = retval;
832 	}
833 
834 	if (datalen > sizeof retval) {
835 		datalen -= sizeof retval;
836 		data += sizeof retval;
837 
838 		client_exitmessage = xmalloc(datalen);
839 		memcpy(client_exitmessage, data, datalen);
840 		client_exitmessage[datalen - 1] = '\0';
841 
842 		client_exitreason = CLIENT_EXIT_MESSAGE_PROVIDED;
843 	}
844 }
845 
846 /* Dispatch imsgs when in wait state (before MSG_READY). */
847 static void
848 client_dispatch_wait(struct imsg *imsg)
849 {
850 	char		*data;
851 	ssize_t		 datalen;
852 	static int	 pledge_applied;
853 
854 	/*
855 	 * "sendfd" is no longer required once all of the identify messages
856 	 * have been sent. We know the server won't send us anything until that
857 	 * point (because we don't ask it to), so we can drop "sendfd" once we
858 	 * get the first message from the server.
859 	 */
860 	if (!pledge_applied) {
861 		if (pledge(
862 		    "stdio rpath wpath cpath unix proc exec tty",
863 		    NULL) != 0)
864 			fatal("pledge failed");
865 		pledge_applied = 1;
866 	}
867 
868 	data = imsg->data;
869 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
870 
871 	switch (imsg->hdr.type) {
872 	case MSG_EXIT:
873 	case MSG_SHUTDOWN:
874 		client_dispatch_exit_message(data, datalen);
875 		client_exitflag = 1;
876 		client_exit();
877 		break;
878 	case MSG_READY:
879 		if (datalen != 0)
880 			fatalx("bad MSG_READY size");
881 
882 		client_attached = 1;
883 		proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
884 		break;
885 	case MSG_VERSION:
886 		if (datalen != 0)
887 			fatalx("bad MSG_VERSION size");
888 
889 		fprintf(stderr, "protocol version mismatch "
890 		    "(client %d, server %u)\n", PROTOCOL_VERSION,
891 		    imsg->hdr.peerid & 0xff);
892 		client_exitval = 1;
893 		proc_exit(client_proc);
894 		break;
895 	case MSG_FLAGS:
896 		if (datalen != sizeof client_flags)
897 			fatalx("bad MSG_FLAGS string");
898 
899 		memcpy(&client_flags, data, sizeof client_flags);
900 		log_debug("new flags are %#llx",
901 		    (unsigned long long)client_flags);
902 		break;
903 	case MSG_SHELL:
904 		if (datalen == 0 || data[datalen - 1] != '\0')
905 			fatalx("bad MSG_SHELL string");
906 
907 		client_exec(data, shell_command);
908 		/* NOTREACHED */
909 	case MSG_DETACH:
910 	case MSG_DETACHKILL:
911 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
912 		break;
913 	case MSG_EXITED:
914 		proc_exit(client_proc);
915 		break;
916 	case MSG_READ_OPEN:
917 		client_read_open(data, datalen);
918 		break;
919 	case MSG_WRITE_OPEN:
920 		client_write_open(data, datalen);
921 		break;
922 	case MSG_WRITE:
923 		client_write_data(data, datalen);
924 		break;
925 	case MSG_WRITE_CLOSE:
926 		client_write_close(data, datalen);
927 		break;
928 	case MSG_OLDSTDERR:
929 	case MSG_OLDSTDIN:
930 	case MSG_OLDSTDOUT:
931 		fprintf(stderr, "server version is too old for client\n");
932 		proc_exit(client_proc);
933 		break;
934 	}
935 }
936 
937 /* Dispatch imsgs in attached state (after MSG_READY). */
938 static void
939 client_dispatch_attached(struct imsg *imsg)
940 {
941 	struct sigaction	 sigact;
942 	char			*data;
943 	ssize_t			 datalen;
944 
945 	data = imsg->data;
946 	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
947 
948 	switch (imsg->hdr.type) {
949 	case MSG_FLAGS:
950 		if (datalen != sizeof client_flags)
951 			fatalx("bad MSG_FLAGS string");
952 
953 		memcpy(&client_flags, data, sizeof client_flags);
954 		log_debug("new flags are %#llx",
955 		    (unsigned long long)client_flags);
956 		break;
957 	case MSG_DETACH:
958 	case MSG_DETACHKILL:
959 		if (datalen == 0 || data[datalen - 1] != '\0')
960 			fatalx("bad MSG_DETACH string");
961 
962 		client_exitsession = xstrdup(data);
963 		client_exittype = imsg->hdr.type;
964 		if (imsg->hdr.type == MSG_DETACHKILL)
965 			client_exitreason = CLIENT_EXIT_DETACHED_HUP;
966 		else
967 			client_exitreason = CLIENT_EXIT_DETACHED;
968 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
969 		break;
970 	case MSG_EXEC:
971 		if (datalen == 0 || data[datalen - 1] != '\0' ||
972 		    strlen(data) + 1 == (size_t)datalen)
973 			fatalx("bad MSG_EXEC string");
974 		client_execcmd = xstrdup(data);
975 		client_execshell = xstrdup(data + strlen(data) + 1);
976 
977 		client_exittype = imsg->hdr.type;
978 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
979 		break;
980 	case MSG_EXIT:
981 		client_dispatch_exit_message(data, datalen);
982 		if (client_exitreason == CLIENT_EXIT_NONE)
983 			client_exitreason = CLIENT_EXIT_EXITED;
984 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
985 		break;
986 	case MSG_EXITED:
987 		if (datalen != 0)
988 			fatalx("bad MSG_EXITED size");
989 
990 		proc_exit(client_proc);
991 		break;
992 	case MSG_SHUTDOWN:
993 		if (datalen != 0)
994 			fatalx("bad MSG_SHUTDOWN size");
995 
996 		proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
997 		client_exitreason = CLIENT_EXIT_SERVER_EXITED;
998 		client_exitval = 1;
999 		break;
1000 	case MSG_SUSPEND:
1001 		if (datalen != 0)
1002 			fatalx("bad MSG_SUSPEND size");
1003 
1004 		memset(&sigact, 0, sizeof sigact);
1005 		sigemptyset(&sigact.sa_mask);
1006 		sigact.sa_flags = SA_RESTART;
1007 		sigact.sa_handler = SIG_DFL;
1008 		if (sigaction(SIGTSTP, &sigact, NULL) != 0)
1009 			fatal("sigaction failed");
1010 		client_suspended = 1;
1011 		kill(getpid(), SIGTSTP);
1012 		break;
1013 	case MSG_LOCK:
1014 		if (datalen == 0 || data[datalen - 1] != '\0')
1015 			fatalx("bad MSG_LOCK string");
1016 
1017 		system(data);
1018 		proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0);
1019 		break;
1020 	}
1021 }
1022