Example #1
0
void
start_cfg(void)
{
	char		*cause = NULL;
	const char	*home;

	cfg_cmd_q = cmdq_new(NULL);
	cfg_cmd_q->emptyfn = cfg_default_done;

	cfg_finished = 0;
	cfg_references = 1;

	cfg_client = TAILQ_FIRST(&clients);
	if (cfg_client != NULL)
		cfg_client->references++;

	if (access(TMUX_CONF, R_OK) == 0) {
		if (load_cfg(TMUX_CONF, cfg_cmd_q, &cause) == -1)
			cfg_add_cause("%s: %s", TMUX_CONF, cause);
	} else if (errno != ENOENT)
		cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno));

	if (cfg_file == NULL && (home = find_home()) != NULL) {
		xasprintf(&cfg_file, "%s/.tmux.conf", home);
		if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
			free(cfg_file);
			cfg_file = NULL;
		}
	}
	if (cfg_file != NULL && load_cfg(cfg_file, cfg_cmd_q, &cause) == -1)
		cfg_add_cause("%s: %s", cfg_file, cause);
	free(cause);

	cmdq_continue(cfg_cmd_q);
}
Example #2
0
int
load_cfg(const char *path, struct cmd_q *cmdq, int quiet)
{
	FILE		*f;
	char		 delim[3] = { '\\', '\\', '\0' };
	u_int		 found;
	size_t		 line = 0;
	char		*buf, *cause1, *p;
	struct cmd_list	*cmdlist;

	log_debug("loading %s", path);
	if ((f = fopen(path, "rb")) == NULL) {
		if (errno == ENOENT && quiet)
			return (0);
		cfg_add_cause("%s: %s", path, strerror(errno));
		return (-1);
	}

	found = 0;
	while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) {
		log_debug("%s: %s", path, buf);

		/* Skip empty lines. */
		p = buf;
		while (isspace((u_char) *p))
			p++;
		if (*p == '\0') {
			free(buf);
			continue;
		}

		/* Parse and run the command. */
		if (cmd_string_parse(p, &cmdlist, path, line, &cause1) != 0) {
			free(buf);
			if (cause1 == NULL)
				continue;
			cfg_add_cause("%s:%zu: %s", path, line, cause1);
			free(cause1);
			continue;
		}
		free(buf);

		if (cmdlist == NULL)
			continue;
		cmdq_append(cmdq, cmdlist, NULL);
		cmd_list_free(cmdlist);
		found++;
	}
	fclose(f);

	return (found);
}
Example #3
0
/*
 * Load configuration file. Returns -1 for an error with a list of messages in
 * causes. Note that causes must be initialised by the caller!
 */
int
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
{
	FILE		*f;
	u_int		 n;
	char		*buf, *line, *cause;
	size_t		 len;
	struct cmd_list	*cmdlist;
	struct cmd_ctx	 ctx;
	int		 retval;

	if ((f = fopen(path, "rb")) == NULL) {
		cfg_add_cause(causes, "%s: %s", path, strerror(errno));
		return (-1);
	}
	n = 0;

	line = NULL;
	retval = 0;
	while ((buf = fgetln(f, &len))) {
		if (buf[len - 1] == '\n')
			buf[len - 1] = '\0';
		else {
			line = xrealloc(line, 1, len + 1);
			memcpy(line, buf, len);
			line[len] = '\0';
			buf = line;
		}
		n++;

		if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
			if (cause == NULL)
				continue;
			cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
			xfree(cause);
			continue;
		}
		if (cmdlist == NULL)
			continue;
		cfg_cause = NULL;

		if (ctxin == NULL) {
			ctx.msgdata = NULL;
			ctx.curclient = NULL;
			ctx.cmdclient = NULL;
		} else {
			ctx.msgdata = ctxin->msgdata;
			ctx.curclient = ctxin->curclient;
			ctx.cmdclient = ctxin->cmdclient;
		}

		ctx.error = cfg_error;
		ctx.print = cfg_print;
		ctx.info = cfg_print;

		cfg_cause = NULL;
		if (cmd_list_exec(cmdlist, &ctx) == 1)
			retval = 1;
		cmd_list_free(cmdlist);
		if (cfg_cause != NULL) {
			cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
			xfree(cfg_cause);
		}
	}
	if (line != NULL)
		xfree(line);
	fclose(f);

	return (retval);
}
Example #4
0
File: cfg.c Project: akracun/tmux
/*
 * Load configuration file. Returns -1 for an error with a list of messages in
 * causes. Note that causes must be initialised by the caller!
 */
enum cmd_retval
load_cfg(const char *path, struct cmd_ctx *ctx, struct causelist *causes)
{
	FILE		*f;
	u_int		 n;
	char		*buf, *copy, *line, *cause;
	size_t		 len, oldlen;
	struct cmd_list	*cmdlist;
	enum cmd_retval	 retval;

	if ((f = fopen(path, "rb")) == NULL) {
		cfg_add_cause(causes, "%s: %s", path, strerror(errno));
		return (CMD_RETURN_ERROR);
	}

	cfg_references++;

	if (ctx != NULL)
		cmd_ref_ctx(ctx);
	else {
		ctx = cmd_get_ctx();
		ctx->error = cfg_error;
		ctx->print = cfg_print;
		ctx->info = cfg_print;
	}

	n = 0;
	line = NULL;
	retval = CMD_RETURN_NORMAL;
	while ((buf = fgetln(f, &len))) {
		/* Trim \n. */
		if (buf[len - 1] == '\n')
			len--;
		log_debug("%s: %.*s", path, (int)len, buf);

		/* Current line is the continuation of the previous one. */
		if (line != NULL) {
			oldlen = strlen(line);
			line = xrealloc(line, 1, oldlen + len + 1);
		} else {
			oldlen = 0;
			line = xmalloc(len + 1);
		}

		/* Append current line to the previous. */
		memcpy(line + oldlen, buf, len);
		line[oldlen + len] = '\0';
		n++;

		/* Continuation: get next line? */
		len = strlen(line);
		if (len > 0 && line[len - 1] == '\\') {
			line[len - 1] = '\0';

			/* Ignore escaped backslash at EOL. */
			if (len > 1 && line[len - 2] != '\\')
				continue;
		}
		copy = line;
		line = NULL;

		/* Skip empty lines. */
		buf = copy;
		while (isspace((u_char)*buf))
			buf++;
		if (*buf == '\0') {
			free(copy);
			continue;
		}

		if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
			free(copy);
			if (cause == NULL)
				continue;
			cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
			free(cause);
			continue;
		}
		free(copy);
		if (cmdlist == NULL)
			continue;

		cfg_cause = NULL;
		switch (cmd_list_exec(cmdlist, ctx)) {
		case CMD_RETURN_YIELD:
			if (retval != CMD_RETURN_ATTACH)
				retval = CMD_RETURN_YIELD;
			break;
		case CMD_RETURN_ATTACH:
			retval = CMD_RETURN_ATTACH;
			break;
		case CMD_RETURN_ERROR:
		case CMD_RETURN_NORMAL:
			break;
		}
		cmd_list_free(cmdlist);
		if (cfg_cause != NULL) {
			cfg_add_cause(causes, "%s: %d: %s", path, n, cfg_cause);
			free(cfg_cause);
		}
	}
	if (line != NULL) {
		cfg_add_cause(causes,
		    "%s: %d: line continuation at end of file", path, n);
		free(line);
	}
	fclose(f);

	cmd_free_ctx(ctx);

	cfg_references--;

	return (retval);
}
Example #5
0
/*
 * Load configuration file. Returns -1 for an error with a list of messages in
 * causes. Note that causes must be initialised by the caller!
 */
int
load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
{
	FILE		*f;
	u_int		 n;
	char		*buf, *line, *cause;
	size_t		 len;
	struct cmd_list	*cmdlist;
	struct cmd_ctx	 ctx;
	int		 retval;

	if ((f = fopen(path, "rb")) == NULL) {
		cfg_add_cause(causes, "%s: %s", path, strerror(errno));
		return (-1);
	}
	n = 0;

	line = NULL;
	retval = 0;
	while ((buf = fgetln(f, &len))) {
		if (buf[len - 1] == '\n')
			len--;

		if (line != NULL)
			line = xrealloc(line, 1, strlen(line) + len + 1);
		else {
			line = xmalloc(len + 1);
			*line = '\0';
		}

		/* Append buffer to line. strncat will terminate. */
		strncat(line, buf, len);
		n++;

		/* Continuation: get next line? */
		len = strlen(line);
		if (len > 0 && line[len - 1] == '\\') {
			line[len - 1] = '\0';
			/* Ignore escaped backslash at EOL. */
			if (len > 1 && line[len - 2] != '\\')
				continue;
		}
		buf = line;
		line = NULL;

		if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
			xfree(buf);
			if (cause == NULL)
				continue;
			cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
			xfree(cause);
			continue;
		} else
			xfree(buf);
		if (cmdlist == NULL)
			continue;
		cfg_cause = NULL;

		if (ctxin == NULL) {
			ctx.msgdata = NULL;
			ctx.curclient = NULL;
			ctx.cmdclient = NULL;
		} else {
			ctx.msgdata = ctxin->msgdata;
			ctx.curclient = ctxin->curclient;
			ctx.cmdclient = ctxin->cmdclient;
		}

		ctx.error = cfg_error;
		ctx.print = cfg_print;
		ctx.info = cfg_print;

		cfg_cause = NULL;
		if (cmd_list_exec(cmdlist, &ctx) == 1)
			retval = 1;
		cmd_list_free(cmdlist);
		if (cfg_cause != NULL) {
			cfg_add_cause(
			    causes, "%s: %d: %s", path, n, cfg_cause);
			xfree(cfg_cause);
		}
	}
	if (line != NULL) {
		cfg_add_cause(causes,
		    "%s: %d: line continuation at end of file", path, n);
		xfree(line);
	}
	fclose(f);

	return (retval);
}