示例#1
0
/* Set user option. */
enum cmd_retval
cmd_set_option_user(struct cmd *self, struct cmd_ctx *ctx, 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(ctx, 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(ctx, 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) {
			ctx->error(ctx, "unknown option: %s", optstr);
			return (CMD_RETURN_ERROR);
		}
		if (valstr != NULL) {
			ctx->error(ctx, "value passed to unset option: %s",
			    optstr);
			return (CMD_RETURN_ERROR);
		}
		options_remove(oo, optstr);
	} else {
		if (valstr == NULL) {
			ctx->error(ctx, "empty value");
			return (CMD_RETURN_ERROR);
		}
		options_set_string(oo, optstr, "%s", valstr);
		if (!args_has(args, 'q'))
			ctx->info(ctx, "set option: %s -> %s", optstr, valstr);
	}
	return (CMD_RETURN_NORMAL);
}
示例#2
0
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
    const struct options_table_entry *oe, struct options *oo,
    const char *value)
{
	struct args	*args = self->args;

	if (args_has(args, 'g')) {
		cmdq_error(cmdq, "can't unset global option: %s", oe->name);
		return (-1);
	}
	if (value != NULL) {
		cmdq_error(cmdq, "value passed to unset option: %s", oe->name);
		return (-1);
	}

	options_remove(oo, oe->name);
	return (0);
}
示例#3
0
/* Unset an option. */
int
cmd_set_option_unset(struct cmd *self, struct cmd_ctx *ctx,
    const struct options_table_entry *oe, struct options *oo)
{
	struct cmd_target_data	*data = self->data;

	if (cmd_check_flag(data->chflags, 'g')) {
		ctx->error(ctx, "can't unset global option: %s", oe->name);
		return (-1);
	}
	if (data->arg2 != NULL) {
		ctx->error(ctx, "value passed to unset option: %s", oe->name);
		return (-1);
	}

	options_remove(oo, oe->name);
	ctx->info(ctx, "unset option: %s", oe->name);
	return (0);
}
示例#4
0
int
cmd_set_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_target_data		*data = self->data;
	const struct set_option_entry	*table;
	struct session			*s;
	struct winlink			*wl;
	struct client			*c;
	struct options			*oo;
	const struct set_option_entry   *entry, *opt;
	struct jobs			*jobs;
	struct job			*job, *nextjob;
	u_int				 i;
	int				 try_again;

	if (cmd_check_flag(data->chflags, 's')) {
		oo = &global_options;
		table = set_option_table;
	} else if (cmd_check_flag(data->chflags, 'w')) {
		table = set_window_option_table;
		if (cmd_check_flag(data->chflags, 'g'))
			oo = &global_w_options;
		else {
			wl = cmd_find_window(ctx, data->target, NULL);
			if (wl == NULL)
				return (-1);
			oo = &wl->window->options;
		}
	} else {
		table = set_session_option_table;
		if (cmd_check_flag(data->chflags, 'g'))
			oo = &global_s_options;
		else {
			s = cmd_find_session(ctx, data->target);
			if (s == NULL)
				return (-1);
			oo = &s->options;
		}
	}

	if (*data->arg == '\0') {
		ctx->error(ctx, "invalid option");
		return (-1);
	}

	entry = NULL;
	for (opt = table; opt->name != NULL; opt++) {
		if (strncmp(opt->name, data->arg, strlen(data->arg)) != 0)
			continue;
		if (entry != NULL) {
			ctx->error(ctx, "ambiguous option: %s", data->arg);
			return (-1);
		}
		entry = opt;

		/* Bail now if an exact match. */
		if (strcmp(entry->name, data->arg) == 0)
			break;
	}
	if (entry == NULL) {
		ctx->error(ctx, "unknown option: %s", data->arg);
		return (-1);
	}

	if (cmd_check_flag(data->chflags, 'u')) {
		if (cmd_check_flag(data->chflags, 'g')) {
			ctx->error(ctx,
			    "can't unset global option: %s", entry->name);
			return (-1);
		}
		if (data->arg2 != NULL) {
			ctx->error(ctx,
			    "value passed to unset option: %s", entry->name);
			return (-1);
		}

		options_remove(oo, entry->name);
		ctx->info(ctx, "unset option: %s", entry->name);
	} else {
		switch (entry->type) {
		case SET_OPTION_STRING:
			cmd_set_option_string(ctx, oo, entry,
			    data->arg2, cmd_check_flag(data->chflags, 'a'));
			break;
		case SET_OPTION_NUMBER:
			cmd_set_option_number(ctx, oo, entry, data->arg2);
			break;
		case SET_OPTION_KEYS:
			cmd_set_option_keys(ctx, oo, entry, data->arg2);
			break;
		case SET_OPTION_COLOUR:
			cmd_set_option_colour(ctx, oo, entry, data->arg2);
			break;
		case SET_OPTION_ATTRIBUTES:
			cmd_set_option_attributes(ctx, oo, entry, data->arg2);
			break;
		case SET_OPTION_FLAG:
			cmd_set_option_flag(ctx, oo, entry, data->arg2);
			break;
		case SET_OPTION_CHOICE:
			cmd_set_option_choice(ctx, oo, entry, data->arg2);
			break;
		}
	}

	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);
	}

	/*
	 * Special-case: kill all persistent jobs if status-left, status-right
	 * or set-titles-string have changed. Persistent jobs are only used by
	 * the status line at the moment so this works XXX.
	 */
	if (strcmp(entry->name, "status-left") == 0 ||
	    strcmp(entry->name, "status-right") == 0 ||
	    strcmp(entry->name, "status") == 0 ||
	    strcmp(entry->name, "set-titles-string") == 0 ||
	    strcmp(entry->name, "window-status-format") == 0) {
		for (i = 0; i < ARRAY_LENGTH(&clients); i++) {
			c = ARRAY_ITEM(&clients, i);
			if (c == NULL || c->session == NULL)
				continue;

			jobs = &c->status_jobs;
			do {
				try_again = 0;
				job = RB_ROOT(jobs);
				while (job != NULL) {
					nextjob = RB_NEXT(jobs, jobs, job);
					if (job->flags & JOB_PERSIST) {
						job_remove(jobs, job);
						try_again = 1;
						break;
					}
					job = nextjob;
				}
			} while (try_again);
			server_redraw_client(c);
		}
	}

	return (0);
}
int
cmd_set_window_option_exec(struct cmd *self, struct cmd_ctx *ctx)
{
	struct cmd_option_data		*data = self->data;
	struct winlink			*wl;
	struct client			*c;
	struct options			*oo;
	const struct set_option_entry   *entry;
	u_int				 i;

	if (data->flags & CMD_GFLAG)
		oo = &global_window_options;
	else {
		if ((wl = cmd_find_window(ctx, data->target, NULL)) == NULL)
			return (-1);
		oo = &wl->window->options;
	}

	if (*data->option == '\0') {
		ctx->error(ctx, "invalid option");
		return (-1);
	}

	entry = NULL;
	for (i = 0; i < NSETWINDOWOPTION; i++) {
		if (strncmp(set_window_option_table[i].name,
		    data->option, strlen(data->option)) != 0)
			continue;
		if (entry != NULL) {
			ctx->error(ctx, "ambiguous option: %s", data->option);
			return (-1);
		}
		entry = &set_window_option_table[i];

		/* Bail now if an exact match. */
		if (strcmp(entry->name, data->option) == 0)
			break;
	}
	if (entry == NULL) {
		ctx->error(ctx, "unknown option: %s", data->option);
		return (-1);
	}

	if (data->flags & CMD_UFLAG) {
		if (data->flags & CMD_GFLAG) {
			ctx->error(ctx,
			    "can't unset global option: %s", entry->name);
			return (-1);
		}
		if (data->value != NULL) {
			ctx->error(ctx,
			    "value passed to unset option: %s", entry->name);
			return (-1);
		}

		options_remove(oo, entry->name);
		ctx->info(ctx, "unset option: %s", entry->name);
	} else {
		switch (entry->type) {
		case SET_OPTION_STRING:
			set_option_string(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_NUMBER:
			set_option_number(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_KEY:
			set_option_key(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_COLOUR:
			set_option_colour(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_ATTRIBUTES:
			set_option_attributes(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_FLAG:
			set_option_flag(ctx, oo, entry, data->value);
			break;
		case SET_OPTION_CHOICE:
			set_option_choice(ctx, oo, entry, data->value);
			break;
		}
	}

	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 (0);
}