예제 #1
0
enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
    const struct options_table_entry *table, struct options *oo)
{
	const struct options_table_entry	*oe;
	struct options_entry			*o;
	const char				*optval;

	o = options_first(oo);
	while (o != NULL) {
		if (*o->name == '@') {
			if (args_has(self->args, 'v'))
				cmdq_print(cmdq, "%s", o->str);
			else
				cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
		}
		o = options_next(o);
	}

	for (oe = table; oe->name != NULL; oe++) {
		if (oe->style != NULL)
			continue;
		if ((o = options_find1(oo, oe->name)) == NULL)
			continue;
		optval = options_table_print_entry(oe, o,
		    args_has(self->args, 'v'));
		if (args_has(self->args, 'v'))
			cmdq_print(cmdq, "%s", optval);
		else
			cmdq_print(cmdq, "%s %s", oe->name, optval);
	}

	return (CMD_RETURN_NORMAL);
}
예제 #2
0
enum cmd_retval
cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
    struct options *oo, int quiet)
{
	struct args				*args = self->args;
	const char				*name = args->argv[0];
	const struct options_table_entry	*table, *oe;
	struct options_entry			*o;
	const char				*optval;

retry:
	if (*name == '@') {
		if ((o = options_find1(oo, name)) == NULL) {
			if (quiet)
				return (CMD_RETURN_NORMAL);
			cmdq_error(cmdq, "unknown option: %s", name);
			return (CMD_RETURN_ERROR);
		}
		if (args_has(self->args, 'v'))
			cmdq_print(cmdq, "%s", o->str);
		else
			cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
		return (CMD_RETURN_NORMAL);
	}

	table = oe = NULL;
	if (options_table_find(name, &table, &oe) != 0) {
		cmdq_error(cmdq, "ambiguous option: %s", name);
		return (CMD_RETURN_ERROR);
	}
	if (oe == NULL) {
		if (quiet)
		    return (CMD_RETURN_NORMAL);
		cmdq_error(cmdq, "unknown option: %s", name);
		return (CMD_RETURN_ERROR);
	}
	if (oe->style != NULL) {
		name = oe->style;
		goto retry;
	}
	if ((o = options_find1(oo, oe->name)) == NULL)
		return (CMD_RETURN_NORMAL);
	optval = options_table_print_entry(oe, o, args_has(self->args, 'v'));
	if (args_has(self->args, 'v'))
		cmdq_print(cmdq, "%s", optval);
	else
		cmdq_print(cmdq, "%s %s", oe->name, optval);
	return (CMD_RETURN_NORMAL);
}
예제 #3
0
static void
cmd_run_shell_print(struct job *job, const char *msg)
{
	struct cmd_run_shell_data	*cdata = job->data;
	struct window_pane		*wp = NULL;
	struct cmd_find_state		 fs;

	if (cdata->wp_id != -1)
		wp = window_pane_find_by_id(cdata->wp_id);
	if (wp == NULL) {
		if (cdata->item != NULL) {
			cmdq_print(cdata->item, "%s", msg);
			return;
		}
		if (cmd_find_from_nothing(&fs, 0) != 0)
			return;
		wp = fs.wp;
		if (wp == NULL)
			return;
	}

	if (window_pane_set_mode(wp, &window_copy_mode, NULL, NULL) == 0)
		window_copy_init_for_output(wp);
	if (wp->mode == &window_copy_mode)
		window_copy_add(wp, "%s", msg);
}
예제 #4
0
static void
cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
    struct options_entry *o, int idx)
{
	struct options_array_item	*a;
	const char			*name = options_name(o);
	char				*value, *tmp = NULL, *escaped;

	if (idx != -1) {
		xasprintf(&tmp, "%s[%d]", name, idx);
		name = tmp;
	} else {
		if (options_isarray(o)) {
			a = options_array_first(o);
			if (a == NULL) {
				if (!args_has(self->args, 'v'))
					cmdq_print(item, "%s", name);
				return;
			}
			while (a != NULL) {
				idx = options_array_item_index(a);
				cmd_show_options_print(self, item, o, idx);
				a = options_array_next(a);
			}
			return;
		}
	}

	value = options_tostring(o, idx, 0);
	if (args_has(self->args, 'v'))
		cmdq_print(item, "%s", value);
	else if (options_isstring(o)) {
		utf8_stravis(&escaped, value, VIS_OCTAL|VIS_TAB|VIS_NL|VIS_DQ);
		cmdq_print(item, "%s \"%s\"", name, escaped);
		free(escaped);
	} else
		cmdq_print(item, "%s %s", name, value);
	free(value);

	free(tmp);
}
예제 #5
0
파일: cfg.c 프로젝트: JonAWhite/tmux
void
cfg_print_causes(struct cmd_q *cmdq)
{
	char	*cause;
	u_int	 i;

	for (i = 0; i < ARRAY_LENGTH(&cfg_causes); i++) {
		cause = ARRAY_ITEM(&cfg_causes, i);
		cmdq_print(cmdq, "%s", cause);
		free(cause);
	}
	ARRAY_FREE(&cfg_causes);
}
예제 #6
0
void
cmd_show_environment_print(struct cmd *self, struct cmd_q *cmdq,
    struct environ_entry *envent)
{
	char	*escaped;

	if (!args_has(self->args, 's')) {
		if (envent->value != NULL)
			cmdq_print(cmdq, "%s=%s", envent->name, envent->value);
		else
			cmdq_print(cmdq, "-%s", envent->name);
		return;
	}

	if (envent->value != NULL) {
		escaped = cmd_show_environment_escape(envent);
		cmdq_print(cmdq, "%s=\"%s\"; export %s;", envent->name, escaped,
		    envent->name);
		free(escaped);
	} else
		cmdq_print(cmdq, "unset %s;", envent->name);
}
예제 #7
0
파일: cfg.c 프로젝트: mosconi/openbsd
void
cfg_print_causes(struct cmd_q *cmdq)
{
	u_int	 i;

	for (i = 0; i < cfg_ncauses; i++) {
		cmdq_print(cmdq, "%s", cfg_causes[i]);
		free(cfg_causes[i]);
	}

	free(cfg_causes);
	cfg_causes = NULL;
	cfg_ncauses = 0;
}
예제 #8
0
void
cmd_run_shell_print(struct job *job, const char *msg)
{
	struct cmd_run_shell_data	*cdata = job->data;
	struct window_pane		*wp = NULL;

	if (cdata->wp_id != -1)
		wp = window_pane_find_by_id(cdata->wp_id);
	if (wp == NULL) {
		cmdq_print(cdata->cmdq, "%s", msg);
		return;
	}

	if (window_pane_set_mode(wp, &window_copy_mode) == 0)
		window_copy_init_for_output(wp);
	if (wp->mode == &window_copy_mode)
		window_copy_add(wp, "%s", msg);
}
예제 #9
0
static enum cmd_retval
cmd_show_options_all(struct cmd *self, struct cmdq_item *item,
    struct options *oo)
{
	struct options_entry			*o;
	struct options_array_item		*a;
	u_int					 idx;
	const struct options_table_entry	*oe;

	o = options_first(oo);
	while (o != NULL) {
		oe = options_table_entry(o);
		if ((self->entry != &cmd_show_hooks_entry &&
		    !args_has(self->args, 'H') &&
		    oe != NULL &&
		    (oe->flags & OPTIONS_TABLE_IS_HOOK)) ||
		    (self->entry == &cmd_show_hooks_entry &&
		    (oe == NULL ||
		    (~oe->flags & OPTIONS_TABLE_IS_HOOK)))) {
			o = options_next(o);
			continue;
		}
		if (!options_isarray(o))
			cmd_show_options_print(self, item, o, -1);
		else if ((a = options_array_first(o)) == NULL) {
			if (!args_has(self->args, 'v'))
				cmdq_print(item, "%s", options_name(o));
		} else {
			while (a != NULL) {
				idx = options_array_item_index(a);
				cmd_show_options_print(self, item, o, idx);
				a = options_array_next(a);
			}
		}
		o = options_next(o);
	}
	return (CMD_RETURN_NORMAL);
}
예제 #10
0
enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct winlink		*wl;
	struct window_pane	*wp;
	const char		*style;

	if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
		wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
		if (wl == NULL)
			return (CMD_RETURN_ERROR);

		if (wl->window->last == NULL) {
			cmdq_error(cmdq, "no last pane");
			return (CMD_RETURN_ERROR);
		}

		if (args_has(self->args, 'e'))
			wl->window->last->flags &= ~PANE_INPUTOFF;
		else if (args_has(self->args, 'd'))
			wl->window->last->flags |= PANE_INPUTOFF;
		else {
			server_unzoom_window(wl->window);
			window_set_active_pane(wl->window, wl->window->last);
			server_status_window(wl->window);
			server_redraw_window_borders(wl->window);
		}

		return (CMD_RETURN_NORMAL);
	}

	if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
		return (CMD_RETURN_ERROR);

	server_unzoom_window(wp->window);
	if (!window_pane_visible(wp)) {
		cmdq_error(cmdq, "pane not visible");
		return (CMD_RETURN_ERROR);
	}

	if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
		if (args_has(args, 'P')) {
			style = args_get(args, 'P');
			if (style_parse(&grid_default_cell, &wp->colgc,
			    style) == -1) {
				cmdq_error(cmdq, "bad style: %s", style);
				return (CMD_RETURN_ERROR);
			}
			wp->flags |= PANE_REDRAW;
		}
		if (args_has(self->args, 'g'))
			cmdq_print(cmdq, "%s", style_tostring(&wp->colgc));
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'L'))
		wp = window_pane_find_left(wp);
	else if (args_has(self->args, 'R'))
		wp = window_pane_find_right(wp);
	else if (args_has(self->args, 'U'))
		wp = window_pane_find_up(wp);
	else if (args_has(self->args, 'D'))
		wp = window_pane_find_down(wp);
	if (wp == NULL) {
		cmdq_error(cmdq, "pane not found");
		return (CMD_RETURN_ERROR);
	}

	if (args_has(self->args, 'e'))
		wp->flags &= ~PANE_INPUTOFF;
	else if (args_has(self->args, 'd'))
		wp->flags |= PANE_INPUTOFF;
	else if (window_set_active_pane(wl->window, wp)) {
		server_status_window(wl->window);
		server_redraw_window_borders(wl->window);
	}

	return (CMD_RETURN_NORMAL);
}
예제 #11
0
static enum cmd_retval
cmd_set_hook_exec(struct cmd *self, struct cmdq_item *item)
{
    struct args	*args = self->args;
    struct cmd_list	*cmdlist;
    struct hooks	*hooks;
    struct hook	*hook;
    char		*cause, *tmp;
    const char	*name, *cmd, *target;

    if (args_has(args, 'g'))
        hooks = global_hooks;
    else {
        if (item->state.tflag.s == NULL) {
            target = args_get(args, 't');
            if (target != NULL)
                cmdq_error(item, "no such session: %s", target);
            else
                cmdq_error(item, "no current session");
            return (CMD_RETURN_ERROR);
        }
        hooks = item->state.tflag.s->hooks;
    }

    if (self->entry == &cmd_show_hooks_entry) {
        hook = hooks_first(hooks);
        while (hook != NULL) {
            tmp = cmd_list_print(hook->cmdlist);
            cmdq_print(item, "%s -> %s", hook->name, tmp);
            free(tmp);

            hook = hooks_next(hook);
        }
        return (CMD_RETURN_NORMAL);
    }

    name = args->argv[0];
    if (*name == '\0') {
        cmdq_error(item, "invalid hook name");
        return (CMD_RETURN_ERROR);
    }
    if (args->argc < 2)
        cmd = NULL;
    else
        cmd = args->argv[1];

    if (args_has(args, 'u')) {
        if (cmd != NULL) {
            cmdq_error(item, "command passed to unset hook: %s",
                       name);
            return (CMD_RETURN_ERROR);
        }
        hooks_remove(hooks, name);
        return (CMD_RETURN_NORMAL);
    }

    if (cmd == NULL) {
        cmdq_error(item, "no command to set hook: %s", name);
        return (CMD_RETURN_ERROR);
    }
    if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
        if (cause != NULL) {
            cmdq_error(item, "%s", cause);
            free(cause);
        }
        return (CMD_RETURN_ERROR);
    }
    hooks_add(hooks, name, cmdlist);
    cmd_list_free(cmdlist);

    return (CMD_RETURN_NORMAL);
}
예제 #12
0
enum cmd_retval
cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args				*args = self->args;
	const struct options_table_entry	*table, *oe;
	struct session				*s;
	struct winlink				*wl;
	struct client				*c;
	struct options				*oo;
	struct window				*w;
	const char				*optstr, *valstr;
	u_int					 i;

	/* Get the option name and value. */
	optstr = args->argv[0];
	if (*optstr == '\0') {
		cmdq_error(cmdq, "invalid option");
		return (CMD_RETURN_ERROR);
	}
	if (args->argc < 2)
		valstr = NULL;
	else
		valstr = args->argv[1];

	/* Is this a user option? */
	if (*optstr == '@')
		return (cmd_set_option_user(self, cmdq, optstr, valstr));

	/* Find the option entry, try each table. */
	table = oe = NULL;
	if (options_table_find(optstr, &table, &oe) != 0) {
		cmdq_error(cmdq, "ambiguous option: %s", optstr);
		return (CMD_RETURN_ERROR);
	}
	if (oe == NULL) {
		cmdq_error(cmdq, "unknown option: %s", optstr);
		return (CMD_RETURN_ERROR);
	}

	/* Work out the tree from the table. */
	if (table == server_options_table)
		oo = &global_options;
	else if (table == window_options_table) {
		if (args_has(self->args, 'g'))
			oo = &global_w_options;
		else {
			wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
			if (wl == NULL) {
				cmdq_error(cmdq,
				    "couldn't set '%s'%s", optstr,
				    (!args_has(args, 't') && !args_has(args,
				    'g')) ? " need target window or -g" : "");
				return (CMD_RETURN_ERROR);
			}
			oo = &wl->window->options;
		}
	} else if (table == session_options_table) {
		if (args_has(self->args, 'g'))
			oo = &global_s_options;
		else {
			s = cmd_find_session(cmdq, args_get(args, 't'), 0);
			if (s == NULL) {
				cmdq_error(cmdq,
				    "couldn't set '%s'%s", optstr,
				    (!args_has(args, 't') && !args_has(args,
				    'g')) ? " need target session or -g" : "");
				return (CMD_RETURN_ERROR);
			}
			oo = &s->options;
		}
	} else {
		cmdq_error(cmdq, "unknown table");
		return (CMD_RETURN_ERROR);
	}

	/* Unset or set the option. */
	if (args_has(args, 'u')) {
		if (cmd_set_option_unset(self, cmdq, oe, oo, valstr) != 0)
			return (CMD_RETURN_ERROR);
	} else {
		if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
			if (!args_has(args, 'q'))
				cmdq_print(cmdq, "already set: %s", optstr);
			return (CMD_RETURN_NORMAL);
		}
		if (cmd_set_option_set(self, cmdq, oe, oo, valstr) != 0)
			return (CMD_RETURN_ERROR);
	}

	/* Start or stop timers when automatic-rename changed. */
	if (strcmp(oe->name, "automatic-rename") == 0) {
		for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
			if ((w = ARRAY_ITEM(&windows, i)) == NULL)
				continue;
			if (options_get_number(&w->options, "automatic-rename"))
				queue_window_name(w);
			else if (event_initialized(&w->name_timer))
				evtimer_del(&w->name_timer);
		}
	}

	/* Update sizes and redraw. May not need it but meh. */
	recalculate_sizes();
	for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
		c = ARRAY_ITEM(&clients, i);
		if (c != NULL && c->session != NULL)
			server_redraw_client(c);
	}

	return (CMD_RETURN_NORMAL);
}
예제 #13
0
/* Set user option. */
enum cmd_retval
cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char* optstr,
    const char *valstr)
{
	struct args	*args = self->args;
	struct session	*s;
	struct winlink	*wl;
	struct options	*oo;

	if (args_has(args, 's'))
		oo = &global_options;
	else if (args_has(self->args, 'w') ||
	    self->entry == &cmd_set_window_option_entry) {
		if (args_has(self->args, 'g'))
			oo = &global_w_options;
		else {
			wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
			if (wl == NULL)
				return (CMD_RETURN_ERROR);
			oo = &wl->window->options;
		}
	} else {
		if (args_has(self->args, 'g'))
			oo = &global_s_options;
		else {
			s = cmd_find_session(cmdq, args_get(args, 't'), 0);
			if (s == NULL)
				return (CMD_RETURN_ERROR);
			oo = &s->options;
		}
	}

	if (args_has(args, 'u')) {
		if (options_find1(oo, optstr) == NULL) {
			cmdq_error(cmdq, "unknown option: %s", optstr);
			return (CMD_RETURN_ERROR);
		}
		if (valstr != NULL) {
			cmdq_error(cmdq, "value passed to unset option: %s",
			    optstr);
			return (CMD_RETURN_ERROR);
		}
		options_remove(oo, optstr);
	} else {
		if (valstr == NULL) {
			cmdq_error(cmdq, "empty value");
			return (CMD_RETURN_ERROR);
		}
		if (args_has(args, 'o') && options_find1(oo, optstr) != NULL) {
			if (!args_has(args, 'q'))
				cmdq_print(cmdq, "already set: %s", optstr);
			return (CMD_RETURN_NORMAL);
		}
		options_set_string(oo, optstr, "%s", valstr);
		if (!args_has(args, 'q')) {
			cmdq_info(cmdq, "set option: %s -> %s", optstr,
			    valstr);
		}
	}
	return (CMD_RETURN_NORMAL);
}
예제 #14
0
static enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct client		*c = item->client;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path, *bufname, *bufdata, *start, *end, *cwd;
	const char		*flags;
	char			*msg, *file, resolved[PATH_MAX];
	size_t			 size, used, msglen, bufsize;
	FILE			*f;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(NULL)) == NULL) {
			cmdq_error(item, "no buffers");
			return (CMD_RETURN_ERROR);
		}
	} else {
		bufname = args_get(args, 'b');
		pb = paste_get_name(bufname);
		if (pb == NULL) {
			cmdq_error(item, "no buffer %s", bufname);
			return (CMD_RETURN_ERROR);
		}
	}
	bufdata = paste_buffer_data(pb, &bufsize);

	if (self->entry == &cmd_show_buffer_entry)
		path = "-";
	else
		path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			cmdq_error(item, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
			goto do_stdout;
		goto do_print;
	}

	if (c != NULL && c->session == NULL && c->cwd != NULL)
		cwd = c->cwd;
	else if ((s = c->session) != NULL && s->cwd != NULL)
		cwd = s->cwd;
	else
		cwd = ".";

	flags = "wb";
	if (args_has(self->args, 'a'))
		flags = "ab";

	if (*path == '/')
		file = xstrdup(path);
	else
		xasprintf(&file, "%s/%s", cwd, path);
	if (realpath(file, resolved) == NULL &&
	    strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) {
		cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG));
		return (CMD_RETURN_ERROR);
	}
	f = fopen(resolved, flags);
	free(file);
	if (f == NULL) {
		cmdq_error(item, "%s: %s", resolved, strerror(errno));
		return (CMD_RETURN_ERROR);
	}

	if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
		cmdq_error(item, "%s: write error", resolved);
		fclose(f);
		return (CMD_RETURN_ERROR);
	}
	fclose(f);

	return (CMD_RETURN_NORMAL);

do_stdout:
	evbuffer_add(c->stdout_data, bufdata, bufsize);
	server_client_push_stdout(c);
	return (CMD_RETURN_NORMAL);

do_print:
	if (bufsize > (INT_MAX / 4) - 1) {
		cmdq_error(item, "buffer too big");
		return (CMD_RETURN_ERROR);
	}
	msg = NULL;

	used = 0;
	while (used != bufsize) {
		start = bufdata + used;
		end = memchr(start, '\n', bufsize - used);
		if (end != NULL)
			size = end - start;
		else
			size = bufsize - used;

		msglen = size * 4 + 1;
		msg = xrealloc(msg, msglen);

		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
		cmdq_print(item, "%s", msg);

		used += size + (end != NULL);
	}

	free(msg);
	return (CMD_RETURN_NORMAL);
}
예제 #15
0
static enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct cmd_find_state	*current = &item->shared->current;
	struct client		*c = cmd_find_client(item, NULL, 1);
	struct winlink		*wl = item->target.wl;
	struct window		*w = wl->window;
	struct session		*s = item->target.s;
	struct window_pane	*wp = item->target.wp, *lastwp, *markedwp;
	char			*pane_title;
	const char		*style;

	if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
		lastwp = w->last;
		if (lastwp == NULL) {
			cmdq_error(item, "no last pane");
			return (CMD_RETURN_ERROR);
		}
		if (args_has(self->args, 'e'))
			lastwp->flags &= ~PANE_INPUTOFF;
		else if (args_has(self->args, 'd'))
			lastwp->flags |= PANE_INPUTOFF;
		else {
			server_unzoom_window(w);
			window_redraw_active_switch(w, lastwp);
			if (window_set_active_pane(w, lastwp)) {
				cmd_find_from_winlink(current, wl, 0);
				server_status_window(w);
				server_redraw_window_borders(w);
			}
		}
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(args, 'm') || args_has(args, 'M')) {
		if (args_has(args, 'm') && !window_pane_visible(wp))
			return (CMD_RETURN_NORMAL);
		lastwp = marked_pane.wp;

		if (args_has(args, 'M') || server_is_marked(s, wl, wp))
			server_clear_marked();
		else
			server_set_marked(s, wl, wp);
		markedwp = marked_pane.wp;

		if (lastwp != NULL) {
			server_redraw_window_borders(lastwp->window);
			server_status_window(lastwp->window);
		}
		if (markedwp != NULL) {
			server_redraw_window_borders(markedwp->window);
			server_status_window(markedwp->window);
		}
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
		if (args_has(args, 'P')) {
			style = args_get(args, 'P');
			if (style_parse(&grid_default_cell, &wp->colgc,
			    style) == -1) {
				cmdq_error(item, "bad style: %s", style);
				return (CMD_RETURN_ERROR);
			}
			wp->flags |= PANE_REDRAW;
		}
		if (args_has(self->args, 'g'))
			cmdq_print(item, "%s", style_tostring(&wp->colgc));
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'L')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_left(wp);
	} else if (args_has(self->args, 'R')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_right(wp);
	} else if (args_has(self->args, 'U')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_up(wp);
	} else if (args_has(self->args, 'D')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_down(wp);
	}
	if (wp == NULL)
		return (CMD_RETURN_NORMAL);

	if (args_has(self->args, 'e')) {
		wp->flags &= ~PANE_INPUTOFF;
		return (CMD_RETURN_NORMAL);
	}
	if (args_has(self->args, 'd')) {
		wp->flags |= PANE_INPUTOFF;
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'T')) {
		pane_title = format_single(item, args_get(self->args, 'T'),
		    c, s, wl, wp);
		screen_set_title(&wp->base, pane_title);
		server_status_window(wp->window);
		free(pane_title);
	}

	if (wp == w->active)
		return (CMD_RETURN_NORMAL);
	server_unzoom_window(wp->window);
	if (!window_pane_visible(wp)) {
		cmdq_error(item, "pane not visible");
		return (CMD_RETURN_ERROR);
	}
	window_redraw_active_switch(w, wp);
	if (window_set_active_pane(w, wp)) {
		cmd_find_from_winlink_pane(current, wl, wp, 0);
		hooks_insert(s->hooks, item, current, "after-select-pane");
		server_status_window(w);
		server_redraw_window_borders(w);
	}

	return (CMD_RETURN_NORMAL);
}
예제 #16
0
static enum cmd_retval
cmd_select_pane_exec(struct cmd *self, struct cmdq_item *item)
{
	struct args		*args = self->args;
	struct winlink		*wl = item->state.tflag.wl;
	struct window		*w = wl->window;
	struct session		*s = item->state.tflag.s;
	struct window_pane	*wp = item->state.tflag.wp, *lastwp, *markedwp;
	const char		*style;

	if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
		if (wl->window->last == NULL) {
			cmdq_error(item, "no last pane");
			return (CMD_RETURN_ERROR);
		}

		if (args_has(self->args, 'e'))
			w->last->flags &= ~PANE_INPUTOFF;
		else if (args_has(self->args, 'd'))
			w->last->flags |= PANE_INPUTOFF;
		else {
			server_unzoom_window(w);
			window_redraw_active_switch(w, w->last);
			if (window_set_active_pane(w, w->last)) {
				server_status_window(w);
				server_redraw_window_borders(w);
			}
		}

		return (CMD_RETURN_NORMAL);
	}

	if (args_has(args, 'm') || args_has(args, 'M')) {
		if (args_has(args, 'm') && !window_pane_visible(wp))
			return (CMD_RETURN_NORMAL);
		lastwp = marked_pane.wp;

		if (args_has(args, 'M') || server_is_marked(s, wl, wp))
			server_clear_marked();
		else
			server_set_marked(s, wl, wp);
		markedwp = marked_pane.wp;

		if (lastwp != NULL) {
			server_redraw_window_borders(lastwp->window);
			server_status_window(lastwp->window);
		}
		if (markedwp != NULL) {
			server_redraw_window_borders(markedwp->window);
			server_status_window(markedwp->window);
		}
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'P') || args_has(self->args, 'g')) {
		if (args_has(args, 'P')) {
			style = args_get(args, 'P');
			if (style_parse(&grid_default_cell, &wp->colgc,
			    style) == -1) {
				cmdq_error(item, "bad style: %s", style);
				return (CMD_RETURN_ERROR);
			}
			wp->flags |= PANE_REDRAW;
		}
		if (args_has(self->args, 'g'))
			cmdq_print(item, "%s", style_tostring(&wp->colgc));
		return (CMD_RETURN_NORMAL);
	}

	if (args_has(self->args, 'L')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_left(wp);
	} else if (args_has(self->args, 'R')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_right(wp);
	} else if (args_has(self->args, 'U')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_up(wp);
	} else if (args_has(self->args, 'D')) {
		server_unzoom_window(wp->window);
		wp = window_pane_find_down(wp);
	}
	if (wp == NULL)
		return (CMD_RETURN_NORMAL);

	if (args_has(self->args, 'e')) {
		wp->flags &= ~PANE_INPUTOFF;
		return (CMD_RETURN_NORMAL);
	}
	if (args_has(self->args, 'd')) {
		wp->flags |= PANE_INPUTOFF;
		return (CMD_RETURN_NORMAL);
	}

	if (wp == w->active)
		return (CMD_RETURN_NORMAL);
	server_unzoom_window(wp->window);
	if (!window_pane_visible(wp)) {
		cmdq_error(item, "pane not visible");
		return (CMD_RETURN_ERROR);
	}
	window_redraw_active_switch(w, wp);
	if (window_set_active_pane(w, wp)) {
		server_status_window(w);
		server_redraw_window_borders(w);
	}

	return (CMD_RETURN_NORMAL);
}
예제 #17
0
enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c = cmdq->client;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path;
	char			*cause, *start, *end, *msg;
	size_t			 size, used, msglen;
	int			 cwd, fd, buffer;
	FILE			*f;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			cmdq_error(cmdq, "no buffers");
			return (CMD_RETURN_ERROR);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	}

	if (self->entry == &cmd_show_buffer_entry)
		path = "-";
	else
		path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		if (c == NULL) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
			goto do_stdout;
		goto do_print;
	}

	if (c != NULL && c->session == NULL)
		cwd = c->cwd;
	else if ((s = cmd_current_session(cmdq, 0)) != NULL)
		cwd = s->cwd;
	else
		cwd = AT_FDCWD;

	f = NULL;
	if (args_has(self->args, 'a')) {
		fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
		if (fd != -1)
			f = fdopen(fd, "ab");
	} else {
		fd = openat(cwd, path, O_CREAT|O_RDWR, 0600);
		if (fd != -1)
			f = fdopen(fd, "wb");
	}
	if (f == NULL) {
		if (fd != -1)
			close(fd);
		cmdq_error(cmdq, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}
	if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
		cmdq_error(cmdq, "%s: fwrite error", path);
		fclose(f);
		return (CMD_RETURN_ERROR);
	}
	fclose(f);

	return (CMD_RETURN_NORMAL);

do_stdout:
	evbuffer_add(c->stdout_data, pb->data, pb->size);
	server_push_stdout(c);
	return (CMD_RETURN_NORMAL);

do_print:
	if (pb->size > (INT_MAX / 4) - 1) {
		cmdq_error(cmdq, "buffer too big");
		return (CMD_RETURN_ERROR);
	}
	msg = NULL;
	msglen = 0;

	used = 0;
	while (used != pb->size) {
		start = pb->data + used;
		end = memchr(start, '\n', pb->size - used);
		if (end != NULL)
			size = end - start;
		else
			size = pb->size - used;

		msglen = size * 4 + 1;
		msg = xrealloc(msg, 1, msglen);

		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
		cmdq_print(cmdq, "%s", msg);

		used += size + (end != NULL);
	}

	free(msg);
	return (CMD_RETURN_NORMAL);
}
예제 #18
0
enum cmd_retval
cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
{
	struct args		*args = self->args;
	struct client		*c;
	struct session          *s;
	struct paste_buffer	*pb;
	const char		*path, *newpath, *wd;
	char			*cause, *start, *end;
	size_t			 size, used;
	int			 buffer;
	mode_t			 mask;
	FILE			*f;
	char			*msg;
	size_t			 msglen;

	if (!args_has(args, 'b')) {
		if ((pb = paste_get_top(&global_buffers)) == NULL) {
			cmdq_error(cmdq, "no buffers");
			return (CMD_RETURN_ERROR);
		}
	} else {
		buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause);
		if (cause != NULL) {
			cmdq_error(cmdq, "buffer %s", cause);
			free(cause);
			return (CMD_RETURN_ERROR);
		}

		pb = paste_get_index(&global_buffers, buffer);
		if (pb == NULL) {
			cmdq_error(cmdq, "no buffer %d", buffer);
			return (CMD_RETURN_ERROR);
		}
	}

	if (self->entry == &cmd_show_buffer_entry)
		path = "-";
	else
		path = args->argv[0];
	if (strcmp(path, "-") == 0) {
		c = cmdq->client;
		if (c == NULL) {
			cmdq_error(cmdq, "can't write to stdout");
			return (CMD_RETURN_ERROR);
		}
		if (c->session == NULL || (c->flags & CLIENT_CONTROL))
			goto do_stdout;
		goto do_print;
	}

	c = cmdq->client;
	if (c != NULL)
		wd = c->cwd;
	else if ((s = cmd_current_session(cmdq, 0)) != NULL) {
		wd = options_get_string(&s->options, "default-path");
		if (*wd == '\0')
			wd = s->cwd;
	} else
		wd = NULL;
	if (wd != NULL && *wd != '\0') {
		newpath = get_full_path(wd, path);
		if (newpath != NULL)
			path = newpath;
	}

	mask = umask(S_IRWXG | S_IRWXO);
	if (args_has(self->args, 'a'))
		f = fopen(path, "ab");
	else
		f = fopen(path, "wb");
	umask(mask);
	if (f == NULL) {
		cmdq_error(cmdq, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}
	if (fwrite(pb->data, 1, pb->size, f) != pb->size) {
		cmdq_error(cmdq, "%s: fwrite error", path);
		fclose(f);
		return (CMD_RETURN_ERROR);
	}
	fclose(f);

	return (CMD_RETURN_NORMAL);

do_stdout:
	evbuffer_add(c->stdout_data, pb->data, pb->size);
	server_push_stdout(c);
	return (CMD_RETURN_NORMAL);

do_print:
	if (pb->size > (INT_MAX / 4) - 1) {
		cmdq_error(cmdq, "buffer too big");
		return (CMD_RETURN_ERROR);
	}
	msg = NULL;
	msglen = 0;

	used = 0;
	while (used != pb->size) {
		start = pb->data + used;
		end = memchr(start, '\n', pb->size - used);
		if (end != NULL)
			size = end - start;
		else
			size = pb->size - used;

		msglen = size * 4 + 1;
		msg = xrealloc(msg, 1, msglen);

		strvisx(msg, start, size, VIS_OCTAL|VIS_TAB);
		cmdq_print(cmdq, "%s", msg);

		used += size + (end != NULL);
	}

	free(msg);
	return (CMD_RETURN_NORMAL);
}