Home | History | Annotate | Line # | Download | only in dist
      1   1.2  christos /* $OpenBSD$ */
      2   1.1      jmmv 
      3   1.1      jmmv /*
      4   1.2  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 
     21   1.2  christos #include <errno.h>
     22   1.2  christos #include <fcntl.h>
     23   1.2  christos #include <stdlib.h>
     24   1.2  christos #include <string.h>
     25   1.2  christos #include <unistd.h>
     26   1.2  christos 
     27   1.1      jmmv #include "tmux.h"
     28   1.1      jmmv 
     29   1.1      jmmv /*
     30   1.1      jmmv  * Attach existing session to the current terminal.
     31   1.1      jmmv  */
     32   1.1      jmmv 
     33   1.3  christos static enum cmd_retval	cmd_attach_session_exec(struct cmd *,
     34   1.3  christos 			    struct cmdq_item *);
     35   1.1      jmmv 
     36   1.1      jmmv const struct cmd_entry cmd_attach_session_entry = {
     37   1.2  christos 	.name = "attach-session",
     38   1.2  christos 	.alias = "attach",
     39   1.2  christos 
     40  1.10       wiz 	.args = { "c:dEf:rt:x", 0, 0, NULL },
     41   1.9  christos 	.usage = "[-dErx] [-c working-directory] [-f flags] "
     42   1.9  christos 	         CMD_TARGET_SESSION_USAGE,
     43   1.2  christos 
     44   1.4  christos 	/* -t is special */
     45   1.2  christos 
     46  1.10       wiz 	.flags = CMD_STARTSERVER|CMD_READONLY,
     47   1.2  christos 	.exec = cmd_attach_session_exec
     48   1.1      jmmv };
     49   1.1      jmmv 
     50   1.2  christos enum cmd_retval
     51   1.4  christos cmd_attach_session(struct cmdq_item *item, const char *tflag, int dflag,
     52   1.9  christos     int xflag, int rflag, const char *cflag, int Eflag, const char *fflag)
     53   1.1      jmmv {
     54   1.9  christos 	struct cmd_find_state	*current = cmdq_get_current(item);
     55   1.9  christos 	struct cmd_find_state	 target;
     56   1.4  christos 	enum cmd_find_type	 type;
     57   1.4  christos 	int			 flags;
     58   1.9  christos 	struct client		*c = cmdq_get_client(item), *c_loop;
     59   1.4  christos 	struct session		*s;
     60   1.4  christos 	struct winlink		*wl;
     61   1.4  christos 	struct window_pane	*wp;
     62   1.9  christos 	char			*cwd, *cause;
     63   1.7  christos 	enum msgtype		 msgtype;
     64   1.1      jmmv 
     65   1.1      jmmv 	if (RB_EMPTY(&sessions)) {
     66   1.3  christos 		cmdq_error(item, "no sessions");
     67   1.2  christos 		return (CMD_RETURN_ERROR);
     68   1.1      jmmv 	}
     69   1.1      jmmv 
     70   1.2  christos 	if (c == NULL)
     71   1.2  christos 		return (CMD_RETURN_NORMAL);
     72  1.10       wiz 
     73   1.2  christos 	if (server_client_check_nested(c)) {
     74   1.3  christos 		cmdq_error(item, "sessions should be nested with care, "
     75   1.2  christos 		    "unset $TMUX to force");
     76   1.2  christos 		return (CMD_RETURN_ERROR);
     77   1.2  christos 	}
     78   1.1      jmmv 
     79   1.4  christos 	if (tflag != NULL && tflag[strcspn(tflag, ":.")] != '\0') {
     80   1.4  christos 		type = CMD_FIND_PANE;
     81   1.4  christos 		flags = 0;
     82   1.4  christos 	} else {
     83   1.4  christos 		type = CMD_FIND_SESSION;
     84   1.4  christos 		flags = CMD_FIND_PREFER_UNATTACHED;
     85   1.4  christos 	}
     86   1.9  christos 	if (cmd_find_target(&target, item, tflag, type, flags) != 0)
     87   1.4  christos 		return (CMD_RETURN_ERROR);
     88   1.9  christos 	s = target.s;
     89   1.9  christos 	wl = target.wl;
     90   1.9  christos 	wp = target.wp;
     91   1.4  christos 
     92   1.2  christos 	if (wl != NULL) {
     93   1.2  christos 		if (wp != NULL)
     94   1.7  christos 			window_set_active_pane(wp->window, wp, 1);
     95   1.2  christos 		session_set_current(s, wl);
     96   1.4  christos 		if (wp != NULL)
     97   1.4  christos 			cmd_find_from_winlink_pane(current, wl, wp, 0);
     98   1.4  christos 		else
     99   1.4  christos 			cmd_find_from_winlink(current, wl, 0);
    100   1.2  christos 	}
    101   1.2  christos 
    102   1.2  christos 	if (cflag != NULL) {
    103   1.9  christos 		cwd = format_single(item, cflag, c, s, wl, wp);
    104   1.2  christos 		free(__UNCONST(s->cwd));
    105   1.9  christos 		s->cwd = cwd;
    106   1.2  christos 	}
    107   1.9  christos 	if (fflag)
    108   1.9  christos 		server_client_set_flags(c, fflag);
    109   1.9  christos 	if (rflag)
    110   1.9  christos 		c->flags |= (CLIENT_READONLY|CLIENT_IGNORESIZE);
    111   1.2  christos 
    112   1.5  christos 	c->last_session = c->session;
    113   1.2  christos 	if (c->session != NULL) {
    114   1.7  christos 		if (dflag || xflag) {
    115   1.7  christos 			if (xflag)
    116   1.7  christos 				msgtype = MSG_DETACHKILL;
    117   1.7  christos 			else
    118   1.7  christos 				msgtype = MSG_DETACH;
    119   1.2  christos 			TAILQ_FOREACH(c_loop, &clients, entry) {
    120   1.2  christos 				if (c_loop->session != s || c == c_loop)
    121   1.1      jmmv 					continue;
    122   1.7  christos 				server_client_detach(c_loop, msgtype);
    123   1.1      jmmv 			}
    124   1.1      jmmv 		}
    125   1.3  christos 		if (!Eflag)
    126   1.3  christos 			environ_update(s->options, c->environ, s->environ);
    127   1.1      jmmv 
    128  1.10       wiz 		server_client_set_session(c, s);
    129   1.9  christos 		if (~cmdq_get_flags(item) & CMDQ_STATE_REPEAT)
    130   1.3  christos 			server_client_set_key_table(c, NULL);
    131   1.2  christos 	} else {
    132   1.2  christos 		if (server_client_open(c, &cause) != 0) {
    133   1.3  christos 			cmdq_error(item, "open terminal failed: %s", cause);
    134   1.2  christos 			free(cause);
    135   1.2  christos 			return (CMD_RETURN_ERROR);
    136   1.1      jmmv 		}
    137   1.1      jmmv 
    138   1.7  christos 		if (dflag || xflag) {
    139   1.7  christos 			if (xflag)
    140   1.7  christos 				msgtype = MSG_DETACHKILL;
    141   1.7  christos 			else
    142   1.7  christos 				msgtype = MSG_DETACH;
    143   1.2  christos 			TAILQ_FOREACH(c_loop, &clients, entry) {
    144   1.2  christos 				if (c_loop->session != s || c == c_loop)
    145   1.2  christos 					continue;
    146   1.7  christos 				server_client_detach(c_loop, msgtype);
    147   1.2  christos 			}
    148   1.2  christos 		}
    149   1.3  christos 		if (!Eflag)
    150   1.3  christos 			environ_update(s->options, c->environ, s->environ);
    151   1.1      jmmv 
    152  1.10       wiz 		server_client_set_session(c, s);
    153   1.2  christos 		server_client_set_key_table(c, NULL);
    154   1.2  christos 
    155   1.2  christos 		if (~c->flags & CLIENT_CONTROL)
    156   1.2  christos 			proc_send(c->peer, MSG_READY, -1, NULL, 0);
    157   1.3  christos 		notify_client("client-attached", c);
    158   1.3  christos 		c->flags |= CLIENT_ATTACHED;
    159   1.1      jmmv 	}
    160   1.1      jmmv 
    161  1.11       wiz 	if (cfg_finished)
    162  1.11       wiz 		cfg_show_causes(s);
    163  1.11       wiz 
    164   1.2  christos 	return (CMD_RETURN_NORMAL);
    165   1.2  christos }
    166   1.2  christos 
    167   1.3  christos static enum cmd_retval
    168   1.3  christos cmd_attach_session_exec(struct cmd *self, struct cmdq_item *item)
    169   1.2  christos {
    170   1.9  christos 	struct args	*args = cmd_get_args(self);
    171   1.2  christos 
    172   1.4  christos 	return (cmd_attach_session(item, args_get(args, 't'),
    173   1.7  christos 	    args_has(args, 'd'), args_has(args, 'x'), args_has(args, 'r'),
    174   1.9  christos 	    args_get(args, 'c'), args_has(args, 'E'), args_get(args, 'f')));
    175   1.1      jmmv }
    176