=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/cmd-show-environment.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- src/usr.bin/tmux/cmd-show-environment.c 2014/10/20 22:29:25 1.9 +++ src/usr.bin/tmux/cmd-show-environment.c 2015/07/13 13:36:29 1.10 @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd-show-environment.c,v 1.9 2014/10/20 22:29:25 nicm Exp $ */ +/* $OpenBSD: cmd-show-environment.c,v 1.10 2015/07/13 13:36:29 nicm Exp $ */ /* * Copyright (c) 2009 Nicholas Marriott @@ -27,16 +27,61 @@ * Show environment. */ -enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *); +enum cmd_retval cmd_show_environment_exec(struct cmd *, struct cmd_q *); +char *cmd_show_environment_escape(struct environ_entry *); +void cmd_show_environment_print(struct cmd *, struct cmd_q *, + struct environ_entry *); + const struct cmd_entry cmd_show_environment_entry = { "show-environment", "showenv", - "gt:", 0, 1, - "[-g] " CMD_TARGET_SESSION_USAGE " [name]", + "gst:", 0, 1, + "[-gs] " CMD_TARGET_SESSION_USAGE " [name]", 0, cmd_show_environment_exec }; +char * +cmd_show_environment_escape(struct environ_entry *envent) +{ + const char *value = envent->value; + char c, *out, *ret; + + out = ret = xmalloc(strlen(value) * 2 + 1); /* at most twice the size */ + while ((c = *value++) != '\0') { + /* POSIX interprets $ ` " and \ in double quotes. */ + if (c == '$' || c == '`' || c == '"' || c == '\\') + *out++ = '\\'; + *out++ = c; + } + *out = '\0'; + + return ret; +} + +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); +} + enum cmd_retval cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq) { @@ -48,7 +93,8 @@ if (args_has(self->args, 'g')) env = &global_environ; else { - if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL) + s = cmd_find_session(cmdq, args_get(args, 't'), 0); + if (s == NULL) return (CMD_RETURN_ERROR); env = &s->environ; } @@ -59,19 +105,11 @@ cmdq_error(cmdq, "unknown variable: %s", args->argv[0]); return (CMD_RETURN_ERROR); } - if (envent->value != NULL) - cmdq_print(cmdq, "%s=%s", envent->name, envent->value); - else - cmdq_print(cmdq, "-%s", envent->name); + cmd_show_environment_print(self, cmdq, envent); return (CMD_RETURN_NORMAL); } - RB_FOREACH(envent, environ, env) { - if (envent->value != NULL) - cmdq_print(cmdq, "%s=%s", envent->name, envent->value); - else - cmdq_print(cmdq, "-%s", envent->name); - } - + RB_FOREACH(envent, environ, env) + cmd_show_environment_print(self, cmdq, envent); return (CMD_RETURN_NORMAL); }