4 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
30 static enum cmd_retval
cmd_show_environment_exec(struct cmd
*,
33 static char *cmd_show_environment_escape(struct environ_entry
*);
34 static void cmd_show_environment_print(struct cmd
*, struct cmdq_item
*,
35 struct environ_entry
*);
37 const struct cmd_entry cmd_show_environment_entry
= {
38 .name
= "show-environment",
41 .args
= { "hgst:", 0, 1, NULL
},
42 .usage
= "[-hgs] " CMD_TARGET_SESSION_USAGE
" [name]",
44 .target
= { 't', CMD_FIND_SESSION
, CMD_FIND_CANFAIL
},
46 .flags
= CMD_AFTERHOOK
,
47 .exec
= cmd_show_environment_exec
51 cmd_show_environment_escape(struct environ_entry
*envent
)
53 const char *value
= envent
->value
;
56 out
= ret
= xmalloc(strlen(value
) * 2 + 1); /* at most twice the size */
57 while ((c
= *value
++) != '\0') {
58 /* POSIX interprets $ ` " and \ in double quotes. */
59 if (c
== '$' || c
== '`' || c
== '"' || c
== '\\')
69 cmd_show_environment_print(struct cmd
*self
, struct cmdq_item
*item
,
70 struct environ_entry
*envent
)
72 struct args
*args
= cmd_get_args(self
);
75 if (!args_has(args
, 'h') && (envent
->flags
& ENVIRON_HIDDEN
))
77 if (args_has(args
, 'h') && (~envent
->flags
& ENVIRON_HIDDEN
))
80 if (!args_has(args
, 's')) {
81 if (envent
->value
!= NULL
)
82 cmdq_print(item
, "%s=%s", envent
->name
, envent
->value
);
84 cmdq_print(item
, "-%s", envent
->name
);
88 if (envent
->value
!= NULL
) {
89 escaped
= cmd_show_environment_escape(envent
);
90 cmdq_print(item
, "%s=\"%s\"; export %s;", envent
->name
, escaped
,
94 cmdq_print(item
, "unset %s;", envent
->name
);
97 static enum cmd_retval
98 cmd_show_environment_exec(struct cmd
*self
, struct cmdq_item
*item
)
100 struct args
*args
= cmd_get_args(self
);
101 struct cmd_find_state
*target
= cmdq_get_target(item
);
103 struct environ_entry
*envent
;
104 const char *tflag
, *name
= args_string(args
, 0);
106 if ((tflag
= args_get(args
, 't')) != NULL
) {
107 if (target
->s
== NULL
) {
108 cmdq_error(item
, "no such session: %s", tflag
);
109 return (CMD_RETURN_ERROR
);
113 if (args_has(args
, 'g'))
114 env
= global_environ
;
116 if (target
->s
== NULL
) {
117 tflag
= args_get(args
, 't');
119 cmdq_error(item
, "no such session: %s", tflag
);
121 cmdq_error(item
, "no current session");
122 return (CMD_RETURN_ERROR
);
124 env
= target
->s
->environ
;
128 envent
= environ_find(env
, name
);
129 if (envent
== NULL
) {
130 cmdq_error(item
, "unknown variable: %s", name
);
131 return (CMD_RETURN_ERROR
);
133 cmd_show_environment_print(self
, item
, envent
);
134 return (CMD_RETURN_NORMAL
);
137 envent
= environ_first(env
);
138 while (envent
!= NULL
) {
139 cmd_show_environment_print(self
, item
, envent
);
140 envent
= environ_next(envent
);
142 return (CMD_RETURN_NORMAL
);