Home | History | Annotate | Line # | Download | only in dist
tmux.c revision 1.14
      1   1.4  christos /* $OpenBSD$ */
      2   1.1      jmmv 
      3   1.1      jmmv /*
      4   1.5  christos  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott (at) gmail.com>
      5   1.1      jmmv  *
      6   1.1      jmmv  * Permission to use, copy, modify, and distribute this software for any
      7   1.1      jmmv  * purpose with or without fee is hereby granted, provided that the above
      8   1.1      jmmv  * copyright notice and this permission notice appear in all copies.
      9   1.1      jmmv  *
     10   1.1      jmmv  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11   1.1      jmmv  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12   1.1      jmmv  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13   1.1      jmmv  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14   1.1      jmmv  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
     15   1.1      jmmv  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
     16   1.1      jmmv  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17   1.1      jmmv  */
     18   1.1      jmmv 
     19   1.1      jmmv #include <sys/types.h>
     20   1.1      jmmv #include <sys/stat.h>
     21  1.11  christos #include <sys/utsname.h>
     22   1.1      jmmv 
     23   1.1      jmmv #include <errno.h>
     24   1.1      jmmv #include <fcntl.h>
     25   1.5  christos #include <langinfo.h>
     26   1.3  christos #include <locale.h>
     27   1.1      jmmv #include <pwd.h>
     28  1.12  christos #include <signal.h>
     29   1.1      jmmv #include <stdlib.h>
     30   1.1      jmmv #include <string.h>
     31   1.4  christos #include <time.h>
     32   1.1      jmmv #include <unistd.h>
     33   1.1      jmmv 
     34   1.1      jmmv #include "tmux.h"
     35   1.1      jmmv 
     36   1.5  christos struct options	*global_options;	/* server options */
     37   1.5  christos struct options	*global_s_options;	/* session options */
     38   1.5  christos struct options	*global_w_options;	/* window options */
     39   1.5  christos struct environ	*global_environ;
     40   1.1      jmmv 
     41   1.5  christos struct timeval	 start_time;
     42   1.5  christos const char	*socket_path;
     43   1.6  christos int		 ptm_fd = -1;
     44   1.7  christos const char	*shell_command;
     45   1.1      jmmv 
     46   1.6  christos static __dead void	 usage(void);
     47   1.8  christos static char		*make_label(const char *, char **);
     48   1.1      jmmv 
     49  1.12  christos static int		 areshell(const char *);
     50   1.6  christos static const char	*getshell(void);
     51   1.1      jmmv 
     52   1.6  christos static __dead void
     53   1.1      jmmv usage(void)
     54   1.1      jmmv {
     55   1.1      jmmv 	fprintf(stderr,
     56  1.12  christos 	    "usage: %s [-2CDlNuvV] [-c shell-command] [-f file] [-L socket-name]\n"
     57  1.12  christos 	    "            [-S socket-path] [-T features] [command [flags]]\n",
     58   1.6  christos 	    getprogname());
     59   1.1      jmmv 	exit(1);
     60   1.1      jmmv }
     61   1.1      jmmv 
     62   1.6  christos static const char *
     63   1.1      jmmv getshell(void)
     64   1.1      jmmv {
     65   1.1      jmmv 	struct passwd	*pw;
     66   1.1      jmmv 	const char	*shell;
     67   1.1      jmmv 
     68   1.1      jmmv 	shell = getenv("SHELL");
     69   1.1      jmmv 	if (checkshell(shell))
     70   1.1      jmmv 		return (shell);
     71   1.1      jmmv 
     72   1.1      jmmv 	pw = getpwuid(getuid());
     73   1.1      jmmv 	if (pw != NULL && checkshell(pw->pw_shell))
     74   1.1      jmmv 		return (pw->pw_shell);
     75   1.1      jmmv 
     76   1.1      jmmv 	return (_PATH_BSHELL);
     77   1.1      jmmv }
     78   1.1      jmmv 
     79  1.12  christos int
     80   1.1      jmmv checkshell(const char *shell)
     81   1.1      jmmv {
     82   1.6  christos 	if (shell == NULL || *shell != '/')
     83   1.3  christos 		return (0);
     84   1.3  christos 	if (areshell(shell))
     85   1.1      jmmv 		return (0);
     86   1.1      jmmv 	if (access(shell, X_OK) != 0)
     87   1.1      jmmv 		return (0);
     88   1.1      jmmv 	return (1);
     89   1.1      jmmv }
     90   1.1      jmmv 
     91  1.12  christos static int
     92   1.1      jmmv areshell(const char *shell)
     93   1.1      jmmv {
     94   1.1      jmmv 	const char	*progname, *ptr;
     95   1.1      jmmv 
     96   1.1      jmmv 	if ((ptr = strrchr(shell, '/')) != NULL)
     97   1.1      jmmv 		ptr++;
     98   1.1      jmmv 	else
     99   1.1      jmmv 		ptr = shell;
    100   1.6  christos 	progname = getprogname();
    101   1.1      jmmv 	if (*progname == '-')
    102   1.1      jmmv 		progname++;
    103   1.1      jmmv 	if (strcmp(ptr, progname) == 0)
    104   1.1      jmmv 		return (1);
    105   1.1      jmmv 	return (0);
    106   1.1      jmmv }
    107   1.1      jmmv 
    108   1.5  christos static char *
    109  1.12  christos expand_path(const char *path, const char *home)
    110  1.12  christos {
    111  1.12  christos 	char			*expanded, *name;
    112  1.12  christos 	const char		*end;
    113  1.12  christos 	struct environ_entry	*value;
    114  1.12  christos 
    115  1.12  christos 	if (strncmp(path, "~/", 2) == 0) {
    116  1.12  christos 		if (home == NULL)
    117  1.12  christos 			return (NULL);
    118  1.12  christos 		xasprintf(&expanded, "%s%s", home, path + 1);
    119  1.12  christos 		return (expanded);
    120  1.12  christos 	}
    121  1.12  christos 
    122  1.12  christos 	if (*path == '$') {
    123  1.12  christos 		end = strchr(path, '/');
    124  1.12  christos 		if (end == NULL)
    125  1.12  christos 			name = xstrdup(path + 1);
    126  1.12  christos 		else
    127  1.12  christos 			name = xstrndup(path + 1, end - path - 1);
    128  1.12  christos 		value = environ_find(global_environ, name);
    129  1.12  christos 		free(name);
    130  1.12  christos 		if (value == NULL)
    131  1.12  christos 			return (NULL);
    132  1.12  christos 		if (end == NULL)
    133  1.12  christos 			end = "";
    134  1.12  christos 		xasprintf(&expanded, "%s%s", value->value, end);
    135  1.12  christos 		return (expanded);
    136  1.12  christos 	}
    137  1.12  christos 
    138  1.12  christos 	return (xstrdup(path));
    139  1.12  christos }
    140  1.12  christos 
    141  1.12  christos static void
    142  1.12  christos expand_paths(const char *s, char ***paths, u_int *n, int ignore_errors)
    143  1.12  christos {
    144  1.12  christos 	const char	*home = find_home();
    145  1.12  christos 	char		*copy, *next, *tmp, resolved[PATH_MAX], *expanded;
    146  1.12  christos 	char		*path;
    147  1.12  christos 	u_int		 i;
    148  1.12  christos 
    149  1.12  christos 	*paths = NULL;
    150  1.12  christos 	*n = 0;
    151  1.12  christos 
    152  1.12  christos 	copy = tmp = xstrdup(s);
    153  1.12  christos 	while ((next = strsep(&tmp, ":")) != NULL) {
    154  1.12  christos 		expanded = expand_path(next, home);
    155  1.12  christos 		if (expanded == NULL) {
    156  1.12  christos 			log_debug("%s: invalid path: %s", __func__, next);
    157  1.12  christos 			continue;
    158  1.12  christos 		}
    159  1.12  christos 		if (realpath(expanded, resolved) == NULL) {
    160  1.12  christos 			log_debug("%s: realpath(\"%s\") failed: %s", __func__,
    161  1.12  christos 			    expanded, strerror(errno));
    162  1.12  christos 			if (ignore_errors) {
    163  1.12  christos 				free(expanded);
    164  1.12  christos 				continue;
    165  1.12  christos 			}
    166  1.12  christos 			path = expanded;
    167  1.12  christos 		} else {
    168  1.12  christos 			path = xstrdup(resolved);
    169  1.12  christos 			free(expanded);
    170  1.12  christos 		}
    171  1.12  christos 		for (i = 0; i < *n; i++) {
    172  1.12  christos 			if (strcmp(path, (*paths)[i]) == 0)
    173  1.12  christos 				break;
    174  1.12  christos 		}
    175  1.12  christos 		if (i != *n) {
    176  1.12  christos 			log_debug("%s: duplicate path: %s", __func__, path);
    177  1.12  christos 			free(path);
    178  1.12  christos 			continue;
    179  1.12  christos 		}
    180  1.12  christos 		*paths = xreallocarray(*paths, (*n) + 1, sizeof *paths);
    181  1.12  christos 		(*paths)[(*n)++] = path;
    182  1.12  christos 	}
    183  1.12  christos 	free(copy);
    184  1.12  christos }
    185  1.12  christos 
    186  1.12  christos static char *
    187   1.8  christos make_label(const char *label, char **cause)
    188   1.1      jmmv {
    189  1.12  christos 	char		**paths, *path, *base;
    190  1.12  christos 	u_int		  i, n;
    191  1.12  christos 	struct stat	  sb;
    192  1.12  christos 	uid_t		  uid;
    193   1.8  christos 
    194   1.8  christos 	*cause = NULL;
    195   1.5  christos 	if (label == NULL)
    196   1.5  christos 		label = "default";
    197   1.1      jmmv 	uid = getuid();
    198   1.5  christos 
    199  1.12  christos 	expand_paths(TMUX_SOCK, &paths, &n, 1);
    200  1.12  christos 	if (n == 0) {
    201  1.12  christos 		xasprintf(cause, "no suitable socket path");
    202  1.12  christos 		return (NULL);
    203   1.8  christos 	}
    204  1.12  christos 	path = paths[0]; /* can only have one socket! */
    205  1.12  christos 	for (i = 1; i < n; i++)
    206  1.12  christos 		free(paths[i]);
    207  1.12  christos 	free(paths);
    208   1.1      jmmv 
    209  1.12  christos 	xasprintf(&base, "%s/tmux-%ld", path, (long)uid);
    210  1.14       wiz 	free(path);
    211  1.14       wiz 	if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST) {
    212  1.14       wiz 		xasprintf(cause, "couldn't create directory %s (%s)", base,
    213  1.14       wiz 		    strerror(errno));
    214   1.5  christos 		goto fail;
    215  1.14       wiz 	}
    216  1.14       wiz 	if (lstat(base, &sb) != 0) {
    217  1.14       wiz 		xasprintf(cause, "couldn't read directory %s (%s)", base,
    218  1.14       wiz 		    strerror(errno));
    219   1.5  christos 		goto fail;
    220  1.14       wiz 	}
    221   1.1      jmmv 	if (!S_ISDIR(sb.st_mode)) {
    222  1.14       wiz 		xasprintf(cause, "%s is not a directory", base);
    223   1.5  christos 		goto fail;
    224   1.1      jmmv 	}
    225   1.4  christos 	if (sb.st_uid != uid || (sb.st_mode & S_IRWXO) != 0) {
    226  1.14       wiz 		xasprintf(cause, "directory %s has unsafe permissions", base);
    227   1.5  christos 		goto fail;
    228   1.1      jmmv 	}
    229  1.12  christos 	xasprintf(&path, "%s/%s", base, label);
    230  1.12  christos 	free(base);
    231   1.5  christos 	return (path);
    232   1.3  christos 
    233   1.5  christos fail:
    234  1.12  christos 	free(base);
    235   1.5  christos 	return (NULL);
    236   1.1      jmmv }
    237   1.1      jmmv 
    238   1.2    martin void
    239   1.2    martin setblocking(int fd, int state)
    240   1.2    martin {
    241   1.2    martin 	int mode;
    242   1.2    martin 
    243   1.2    martin 	if ((mode = fcntl(fd, F_GETFL)) != -1) {
    244   1.2    martin 		if (!state)
    245   1.2    martin 			mode |= O_NONBLOCK;
    246   1.2    martin 		else
    247   1.2    martin 			mode &= ~O_NONBLOCK;
    248   1.2    martin 		fcntl(fd, F_SETFL, mode);
    249   1.2    martin 	}
    250   1.2    martin }
    251   1.2    martin 
    252  1.12  christos uint64_t
    253  1.12  christos get_timer(void)
    254  1.12  christos {
    255  1.12  christos 	struct timespec	ts;
    256  1.12  christos 
    257  1.12  christos 	/*
    258  1.12  christos 	 * We want a timestamp in milliseconds suitable for time measurement,
    259  1.12  christos 	 * so prefer the monotonic clock.
    260  1.12  christos 	 */
    261  1.12  christos 	if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
    262  1.12  christos 		clock_gettime(CLOCK_REALTIME, &ts);
    263  1.12  christos 	return ((ts.tv_sec * 1000ULL) + (ts.tv_nsec / 1000000ULL));
    264  1.12  christos }
    265  1.12  christos 
    266  1.12  christos const char *
    267  1.12  christos sig2name(int signo)
    268  1.12  christos {
    269  1.12  christos      static char	s[11];
    270  1.12  christos 
    271  1.12  christos #ifdef HAVE_SYS_SIGNAME
    272  1.12  christos      if (signo > 0 && signo < NSIG)
    273  1.12  christos 	     return (sys_signame[signo]);
    274  1.12  christos #endif
    275  1.12  christos      xsnprintf(s, sizeof s, "%d", signo);
    276  1.12  christos      return (s);
    277  1.12  christos }
    278  1.12  christos 
    279   1.4  christos const char *
    280   1.9  christos find_cwd(void)
    281   1.9  christos {
    282   1.9  christos 	char		 resolved1[PATH_MAX], resolved2[PATH_MAX];
    283   1.9  christos 	static char	 cwd[PATH_MAX];
    284   1.9  christos 	const char	*pwd;
    285   1.9  christos 
    286   1.9  christos 	if (getcwd(cwd, sizeof cwd) == NULL)
    287   1.9  christos 		return (NULL);
    288   1.9  christos 	if ((pwd = getenv("PWD")) == NULL || *pwd == '\0')
    289   1.9  christos 		return (cwd);
    290   1.9  christos 
    291   1.9  christos 	/*
    292   1.9  christos 	 * We want to use PWD so that symbolic links are maintained,
    293   1.9  christos 	 * but only if it matches the actual working directory.
    294   1.9  christos 	 */
    295   1.9  christos 	if (realpath(pwd, resolved1) == NULL)
    296   1.9  christos 		return (cwd);
    297   1.9  christos 	if (realpath(cwd, resolved2) == NULL)
    298   1.9  christos 		return (cwd);
    299   1.9  christos 	if (strcmp(resolved1, resolved2) != 0)
    300   1.9  christos 		return (cwd);
    301   1.9  christos 	return (pwd);
    302   1.9  christos }
    303   1.9  christos 
    304   1.9  christos const char *
    305   1.4  christos find_home(void)
    306   1.1      jmmv {
    307   1.4  christos 	struct passwd		*pw;
    308   1.4  christos 	static const char	*home;
    309   1.1      jmmv 
    310   1.4  christos 	if (home != NULL)
    311   1.4  christos 		return (home);
    312   1.1      jmmv 
    313   1.4  christos 	home = getenv("HOME");
    314   1.4  christos 	if (home == NULL || *home == '\0') {
    315   1.4  christos 		pw = getpwuid(getuid());
    316   1.4  christos 		if (pw != NULL)
    317   1.4  christos 			home = pw->pw_dir;
    318   1.4  christos 		else
    319   1.4  christos 			home = NULL;
    320   1.4  christos 	}
    321   1.1      jmmv 
    322   1.4  christos 	return (home);
    323   1.1      jmmv }
    324   1.1      jmmv 
    325  1.11  christos const char *
    326  1.11  christos getversion(void)
    327  1.11  christos {
    328  1.14       wiz 	return (TMUX_VERSION);
    329  1.11  christos }
    330  1.11  christos 
    331   1.1      jmmv int
    332   1.1      jmmv main(int argc, char **argv)
    333   1.1      jmmv {
    334  1.12  christos 	char					*path = NULL, *label = NULL;
    335  1.12  christos 	char					*cause, **var;
    336  1.12  christos 	const char				*s, *cwd;
    337  1.13  christos 	int					 opt, keys, feat = 0, fflag = 0;
    338  1.12  christos 	uint64_t				 flags = 0;
    339   1.6  christos 	const struct options_table_entry	*oe;
    340  1.12  christos 	u_int					 i;
    341   1.5  christos 
    342   1.7  christos 	if (setlocale(LC_CTYPE, "en_US.UTF-8") == NULL &&
    343   1.7  christos 	    setlocale(LC_CTYPE, "C.UTF-8") == NULL) {
    344   1.5  christos 		if (setlocale(LC_CTYPE, "") == NULL)
    345   1.5  christos 			errx(1, "invalid LC_ALL, LC_CTYPE or LANG");
    346   1.5  christos 		s = nl_langinfo(CODESET);
    347   1.6  christos 		if (strcasecmp(s, "UTF-8") != 0 && strcasecmp(s, "UTF8") != 0)
    348   1.5  christos 			errx(1, "need UTF-8 locale (LC_CTYPE) but have %s", s);
    349   1.5  christos 	}
    350   1.1      jmmv 
    351   1.3  christos 	setlocale(LC_TIME, "");
    352   1.4  christos 	tzset();
    353   1.4  christos 
    354   1.4  christos 	if (**argv == '-')
    355   1.4  christos 		flags = CLIENT_LOGIN;
    356   1.3  christos 
    357  1.12  christos 	global_environ = environ_create();
    358  1.12  christos 	for (var = environ; *var != NULL; var++)
    359  1.12  christos 		environ_put(global_environ, *var, 0);
    360  1.12  christos 	if ((cwd = find_cwd()) != NULL)
    361  1.12  christos 		environ_set(global_environ, "PWD", 0, "%s", cwd);
    362  1.12  christos 	expand_paths(TMUX_CONF, &cfg_files, &cfg_nfiles, 1);
    363  1.12  christos 
    364  1.12  christos 	while ((opt = getopt(argc, argv, "2c:CDdf:lL:NqS:T:uUvV")) != -1) {
    365   1.1      jmmv 		switch (opt) {
    366   1.1      jmmv 		case '2':
    367  1.12  christos 			tty_add_features(&feat, "256", ":,");
    368   1.1      jmmv 			break;
    369   1.1      jmmv 		case 'c':
    370   1.7  christos 			shell_command = optarg;
    371   1.1      jmmv 			break;
    372  1.12  christos 		case 'D':
    373  1.12  christos 			flags |= CLIENT_NOFORK;
    374  1.12  christos 			break;
    375   1.3  christos 		case 'C':
    376   1.3  christos 			if (flags & CLIENT_CONTROL)
    377   1.3  christos 				flags |= CLIENT_CONTROLCONTROL;
    378   1.3  christos 			else
    379   1.3  christos 				flags |= CLIENT_CONTROL;
    380   1.3  christos 			break;
    381   1.1      jmmv 		case 'f':
    382  1.13  christos 			if (!fflag) {
    383  1.13  christos 				fflag = 1;
    384  1.13  christos 				for (i = 0; i < cfg_nfiles; i++)
    385  1.13  christos 					free(cfg_files[i]);
    386  1.13  christos 				cfg_nfiles = 0;
    387  1.13  christos 			}
    388  1.13  christos 			cfg_files = xreallocarray(cfg_files, cfg_nfiles + 1,
    389  1.13  christos 			    sizeof *cfg_files);
    390  1.13  christos 			cfg_files[cfg_nfiles++] = xstrdup(optarg);
    391  1.12  christos 			cfg_quiet = 0;
    392   1.1      jmmv 			break;
    393  1.11  christos  		case 'V':
    394  1.11  christos 			printf("%s %s\n", getprogname(), getversion());
    395  1.11  christos  			exit(0);
    396   1.1      jmmv 		case 'l':
    397   1.4  christos 			flags |= CLIENT_LOGIN;
    398   1.1      jmmv 			break;
    399   1.1      jmmv 		case 'L':
    400   1.3  christos 			free(label);
    401   1.1      jmmv 			label = xstrdup(optarg);
    402   1.1      jmmv 			break;
    403  1.12  christos 		case 'N':
    404  1.12  christos 			flags |= CLIENT_NOSTARTSERVER;
    405  1.12  christos 			break;
    406   1.1      jmmv 		case 'q':
    407   1.1      jmmv 			break;
    408   1.1      jmmv 		case 'S':
    409   1.3  christos 			free(path);
    410   1.1      jmmv 			path = xstrdup(optarg);
    411   1.1      jmmv 			break;
    412  1.12  christos 		case 'T':
    413  1.12  christos 			tty_add_features(&feat, optarg, ":,");
    414  1.12  christos 			break;
    415   1.1      jmmv 		case 'u':
    416   1.3  christos 			flags |= CLIENT_UTF8;
    417   1.1      jmmv 			break;
    418   1.1      jmmv 		case 'v':
    419   1.5  christos 			log_add_level();
    420   1.1      jmmv 			break;
    421   1.1      jmmv 		default:
    422   1.1      jmmv 			usage();
    423   1.1      jmmv 		}
    424   1.1      jmmv 	}
    425   1.1      jmmv 	argc -= optind;
    426   1.1      jmmv 	argv += optind;
    427   1.1      jmmv 
    428   1.7  christos 	if (shell_command != NULL && argc != 0)
    429   1.1      jmmv 		usage();
    430  1.12  christos 	if ((flags & CLIENT_NOFORK) && argc != 0)
    431  1.12  christos 		usage();
    432   1.1      jmmv 
    433   1.7  christos 	if ((ptm_fd = getptmfd()) == -1)
    434   1.7  christos 		err(1, "getptmfd");
    435   1.5  christos 	if (pledge("stdio rpath wpath cpath flock fattr unix getpw sendfd "
    436   1.5  christos 	    "recvfd proc exec tty ps", NULL) != 0)
    437   1.5  christos 		err(1, "pledge");
    438   1.1      jmmv 
    439   1.5  christos 	/*
    440   1.5  christos 	 * tmux is a UTF-8 terminal, so if TMUX is set, assume UTF-8.
    441   1.5  christos 	 * Otherwise, if the user has set LC_ALL, LC_CTYPE or LANG to contain
    442   1.5  christos 	 * UTF-8, it is a safe assumption that either they are using a UTF-8
    443   1.5  christos 	 * terminal, or if not they know that output from UTF-8-capable
    444   1.5  christos 	 * programs may be wrong.
    445   1.5  christos 	 */
    446   1.5  christos 	if (getenv("TMUX") != NULL)
    447   1.5  christos 		flags |= CLIENT_UTF8;
    448   1.5  christos 	else {
    449   1.5  christos 		s = getenv("LC_ALL");
    450   1.5  christos 		if (s == NULL || *s == '\0')
    451   1.5  christos 			s = getenv("LC_CTYPE");
    452   1.5  christos 		if (s == NULL || *s == '\0')
    453   1.5  christos 			s = getenv("LANG");
    454   1.5  christos 		if (s == NULL || *s == '\0')
    455   1.5  christos 			s = "";
    456   1.5  christos 		if (strcasestr(s, "UTF-8") != NULL ||
    457   1.5  christos 		    strcasestr(s, "UTF8") != NULL)
    458   1.3  christos 			flags |= CLIENT_UTF8;
    459   1.1      jmmv 	}
    460   1.1      jmmv 
    461   1.5  christos 	global_options = options_create(NULL);
    462   1.5  christos 	global_s_options = options_create(NULL);
    463   1.6  christos 	global_w_options = options_create(NULL);
    464   1.6  christos 	for (oe = options_table; oe->name != NULL; oe++) {
    465  1.10  christos 		if (oe->scope & OPTIONS_TABLE_SERVER)
    466   1.6  christos 			options_default(global_options, oe);
    467  1.10  christos 		if (oe->scope & OPTIONS_TABLE_SESSION)
    468   1.6  christos 			options_default(global_s_options, oe);
    469  1.10  christos 		if (oe->scope & OPTIONS_TABLE_WINDOW)
    470   1.6  christos 			options_default(global_w_options, oe);
    471   1.6  christos 	}
    472   1.1      jmmv 
    473   1.6  christos 	/*
    474   1.6  christos 	 * The default shell comes from SHELL or from the user's passwd entry
    475   1.6  christos 	 * if available.
    476   1.6  christos 	 */
    477  1.12  christos 	options_set_string(global_s_options, "default-shell", 0, "%s",
    478  1.12  christos 	    getshell());
    479   1.1      jmmv 
    480   1.2    martin 	/* Override keys to vi if VISUAL or EDITOR are set. */
    481   1.1      jmmv 	if ((s = getenv("VISUAL")) != NULL || (s = getenv("EDITOR")) != NULL) {
    482  1.12  christos 		options_set_string(global_options, "editor", 0, "%s", s);
    483   1.1      jmmv 		if (strrchr(s, '/') != NULL)
    484   1.1      jmmv 			s = strrchr(s, '/') + 1;
    485   1.1      jmmv 		if (strstr(s, "vi") != NULL)
    486   1.1      jmmv 			keys = MODEKEY_VI;
    487   1.2    martin 		else
    488   1.2    martin 			keys = MODEKEY_EMACS;
    489   1.5  christos 		options_set_number(global_s_options, "status-keys", keys);
    490   1.5  christos 		options_set_number(global_w_options, "mode-keys", keys);
    491   1.1      jmmv 	}
    492   1.1      jmmv 
    493   1.1      jmmv 	/*
    494   1.5  christos 	 * If socket is specified on the command-line with -S or -L, it is
    495   1.5  christos 	 * used. Otherwise, $TMUX is checked and if that fails "default" is
    496   1.5  christos 	 * used.
    497   1.1      jmmv 	 */
    498   1.5  christos 	if (path == NULL && label == NULL) {
    499   1.5  christos 		s = getenv("TMUX");
    500   1.5  christos 		if (s != NULL && *s != '\0' && *s != ',') {
    501   1.5  christos 			path = xstrdup(s);
    502   1.6  christos 			path[strcspn(path, ",")] = '\0';
    503   1.1      jmmv 		}
    504   1.1      jmmv 	}
    505  1.12  christos 	if (path == NULL) {
    506  1.12  christos 		if ((path = make_label(label, &cause)) == NULL) {
    507  1.12  christos 			if (cause != NULL) {
    508  1.12  christos 				fprintf(stderr, "%s\n", cause);
    509  1.12  christos 				free(cause);
    510  1.12  christos 			}
    511  1.12  christos 			exit(1);
    512   1.8  christos 		}
    513  1.12  christos 		flags |= CLIENT_DEFAULTSOCKET;
    514   1.3  christos 	}
    515   1.5  christos 	socket_path = path;
    516   1.5  christos 	free(label);
    517   1.1      jmmv 
    518   1.1      jmmv 	/* Pass control to the client. */
    519  1.12  christos 	exit(client_main(osdep_event_init(), argc, argv, flags, feat));
    520   1.1      jmmv }
    521