Browse Source

Made variable expansion optional

This patch is intended to improve support for high-level plugins that
deal with params and vars directly instead of requiring expansion.
Ingo Albrecht 3 years ago
parent
commit
d5301c25f3

+ 6 - 0
clish.xsd

@@ -206,6 +206,8 @@
 *
 * [default_shebang] - The default shebang for all commands.
 *
+* [default_expand] - Expand variables in actions by default.
+*
 * [timeout] - The idle timeout. The clish will exit if user
 *	have not press any key while this timeout.
 *
@@ -225,6 +227,7 @@
 		<xs:attribute name="view" type="xs:string" use="required"/>
 		<xs:attribute name="viewid" type="xs:string" use="optional"/>
 		<xs:attribute name="default_shebang" type="xs:string" use="optional"/>
+		<xs:attribute name="default_expand" type="xs:string" use="optional"/>
 		<xs:attribute name="timeout" type="xs:string" use="optional"/>
 		<xs:attribute name="default_plugin" type="bool_t" use="optional" default="true"/>
 <!-- legacy -->	<xs:attribute name="lock" type="bool_t" use="optional" default="true"/>
@@ -402,6 +405,8 @@
 * [shebang] - specify the programm to execute the action
 *	script.
 *
+* [expand="true/false"] - specify expansion override.
+*
 * [lock="true/false"] - the boolean field that specify to lock lockfile while
 *	action execution or not. Default is true. In a case the
 *	LEGACY macro is specified while klish building the
@@ -424,6 +429,7 @@
 			<xs:extension base="xs:string">
 				<xs:attribute name="builtin" type="xs:string" use="optional"/>
 				<xs:attribute name="shebang" type="xs:string" use="optional"/>
+				<xs:attribute name="expand" type="bool_t" use="optional"/>
 				<xs:attribute name="lock" type="bool_t" use="optional" default="true"/>
 				<xs:attribute name="interrupt" type="bool_t" use="optional" default="false"/>
 				<xs:attribute name="interactive" type="bool_t" use="optional" default="false"/>

+ 2 - 0
clish/action.h

@@ -28,5 +28,7 @@ _CLISH_SET(action, bool_t, interactive);
 _CLISH_GET(action, bool_t, interactive);
 _CLISH_SET(action, bool_t, permanent);
 _CLISH_GET(action, bool_t, permanent);
+_CLISH_SET(action, tri_t, expand);
+_CLISH_GET(action, tri_t, expand);
 
 #endif // _clish_action_h

+ 3 - 0
clish/action/action.c

@@ -21,6 +21,7 @@ static void clish_action_init(clish_action_t *this)
 	this->lock = BOOL_TRUE;
 	this->interrupt = BOOL_FALSE;
 	this->permanent = BOOL_FALSE;
+	this->expand = TRI_UNDEFINED;
 }
 
 /*--------------------------------------------------------- */
@@ -60,6 +61,8 @@ CLISH_SET(action, bool_t, interactive);
 CLISH_GET(action, bool_t, interactive);
 CLISH_SET(action, bool_t, permanent);
 CLISH_GET(action, bool_t, permanent);
+CLISH_SET(action, tri_t, expand);
+CLISH_GET(action, tri_t, expand);
 
 _CLISH_SET_STR(action, shebang)
 {

+ 1 - 0
clish/action/action_dump.c

@@ -21,6 +21,7 @@ void clish_action_dump(const clish_action_t *this)
 	lub_dump_printf("interrupt   : %s\n", LUB_DUMP_BOOL(this->interrupt));
 	lub_dump_printf("interactive : %s\n", LUB_DUMP_BOOL(this->interactive));
 	lub_dump_printf("permanent   : %s\n", LUB_DUMP_BOOL(this->permanent));
+	lub_dump_printf("expand      : %s\n", LUB_DUMP_TRI(this->expand));
 
 	lub_dump_undent();
 }

+ 1 - 0
clish/action/private.h

@@ -12,4 +12,5 @@ struct clish_action_s {
 	bool_t interrupt;
 	bool_t interactive;
 	bool_t permanent; // if true then ACTION will be executed on dryrun
+	tri_t expand; // if true variables are expanded even if sym says not to
 };

+ 2 - 0
clish/plugin.h

@@ -78,6 +78,8 @@ _CLISH_SET(sym, const void *, func);
 _CLISH_GET(sym, const void *, func);
 _CLISH_SET(sym, bool_t, permanent);
 _CLISH_GET(sym, bool_t, permanent);
+_CLISH_SET(sym, tri_t, expand);
+_CLISH_GET(sym, tri_t, expand);
 _CLISH_SET_STR(sym, name);
 _CLISH_GET_STR(sym, name);
 _CLISH_SET(sym, clish_plugin_t *, plugin);

+ 1 - 0
clish/plugin/plugin_dump.c

@@ -40,6 +40,7 @@ void clish_sym_dump(const clish_sym_t *this)
 	}
 	lub_dump_printf("type      : %s\n", type);
 	lub_dump_printf("permanent : %s\n", LUB_DUMP_BOOL(this->permanent));
+	lub_dump_printf("expand    : %s\n", LUB_DUMP_TRI(this->expand));
 	lub_dump_printf("plugin    : %p\n", this->plugin);
 	lub_dump_undent();
 }

+ 1 - 0
clish/plugin/private.h

@@ -15,6 +15,7 @@ struct clish_sym_s {
 	int type; /* Function type */
 	clish_sym_api_e api; /* Function API */
 	bool_t permanent; /* If permanent the dry-run can't switch it off */
+	tri_t expand; /* If action scripts should be expanded */
 	clish_plugin_t *plugin; /* Parent plugin */
 };
 

+ 3 - 0
clish/plugin/sym.c

@@ -38,6 +38,7 @@ clish_sym_t *clish_sym_new(const char *name, void *func, int type)
 	this->type = type;
 	this->api = CLISH_SYM_API_SIMPLE;
 	this->permanent = BOOL_FALSE;
+	this->expand = TRI_UNDEFINED;
 
 	return this;
 }
@@ -70,6 +71,8 @@ CLISH_SET(sym, const void *, func);
 CLISH_GET(sym, const void *, func);
 CLISH_SET(sym, bool_t, permanent);
 CLISH_GET(sym, bool_t, permanent);
+CLISH_SET(sym, tri_t, expand);
+CLISH_GET(sym, tri_t, expand);
 CLISH_SET_STR(sym, name);
 CLISH_GET_STR(sym, name);
 CLISH_SET(sym, clish_plugin_t *, plugin);

+ 3 - 0
clish/shell.h

@@ -54,6 +54,7 @@ void clish_context__set_pargv(void *instance, clish_pargv_t *pargv);
 clish_pargv_t *clish_context__get_pargv(const void *instance);
 void clish_context__set_action(void *instance, const clish_action_t *action);
 const clish_action_t *clish_context__get_action(const void *instance);
+bool_t clish_context__get_expand(const clish_context_t *context);
 _END_C_DECL
 
 /* Shell */
@@ -136,6 +137,8 @@ _CLISH_SET_STR(shell, lockfile);
 _CLISH_GET_STR(shell, lockfile);
 _CLISH_SET_STR(shell, default_shebang);
 _CLISH_GET_STR(shell, default_shebang);
+_CLISH_SET(shell, bool_t, default_expand);
+_CLISH_GET(shell, bool_t, default_expand);
 _CLISH_SET(shell, unsigned int, idle_timeout);
 _CLISH_SET(shell, unsigned int, wdog_timeout);
 _CLISH_GET(shell, unsigned int, wdog_timeout);

+ 19 - 0
clish/shell/context.c

@@ -103,4 +103,23 @@ const clish_action_t *clish_context__get_action(const void *this)
 	return context->action;
 }
 
+/*----------------------------------------------------------- */
+bool_t clish_context__get_expand(const clish_context_t *context)
+{
+	bool_t res;
+	const clish_shell_t *shell = clish_context__get_shell(context);
+	const clish_action_t *action = clish_context__get_action(context);
+	const clish_sym_t *sym = clish_action__get_builtin(action);
+
+	/* get global default */
+	res = clish_shell__get_default_expand(shell);
+	/* allow builtin to override */
+	res = lub_tri_default(clish_sym__get_expand(sym), res);
+	/* allow action to override */
+	res = lub_tri_default(clish_action__get_expand(action), res);
+
+	/* return result */
+	return res;
+}
+
 /*--------------------------------------------------------- */

+ 1 - 0
clish/shell/private.h

@@ -73,6 +73,7 @@ struct clish_shell_s {
 	konf_client_t *client;
 	char *lockfile;
 	char *default_shebang;
+	bool_t default_expand;
 	char *fifo_temp; /* The template of temporary FIFO file name */
 	struct passwd *user; /* Current user information */
 

+ 8 - 1
clish/shell/shell_execute.c

@@ -320,6 +320,7 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
 {
 	int result = -1;
 	const clish_sym_t *sym;
+	const char *rscript;
 	char *script;
 	const void *func = NULL; /* We don't know the func API at this time */
 	const clish_action_t *action = clish_context__get_action(context);
@@ -340,7 +341,13 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
 		fprintf(stderr, "Error: Default ACTION symbol is not specified.\n");
 		return -1;
 	}
-	script = clish_shell_expand(clish_action__get_script(action), SHELL_VAR_ACTION, context);
+
+	/* Expand variables, but only if the sym or action want it */
+	rscript = clish_action__get_script(action);
+	if(clish_context__get_expand(context))
+		script = clish_shell_expand(rscript, SHELL_VAR_ACTION, context);
+	else
+		script = lub_string_dup(rscript);
 
 	/* Ignore and block SIGINT, SIGQUIT, SIGHUP.
 	 * The SIG_IGN is not a case because it will be inherited

+ 1 - 0
clish/shell/shell_new.c

@@ -66,6 +66,7 @@ static void clish_shell_init(clish_shell_t * this,
 	this->client = NULL;
 	this->lockfile = lub_string_dup(CLISH_LOCK_PATH);
 	this->default_shebang = lub_string_dup("/bin/sh");
+	this->default_expand = BOOL_TRUE; /* Expand variables in actions by default. */
 	this->machine_interface = BOOL_FALSE; /* Human oriented protocol by default. */
 	this->interactive = BOOL_TRUE; /* The interactive shell by default. */
 	this->log = BOOL_FALSE; /* Disable logging by default */

+ 2 - 0
clish/shell/shell_var.c

@@ -541,3 +541,5 @@ char *clish_shell_expand_var_ex(const char *name, clish_context_t *context, clis
 }
 
 /*----------------------------------------------------------- */
+CLISH_SET(shell, bool_t, default_expand);
+CLISH_GET(shell, bool_t, default_expand);

+ 13 - 0
clish/shell/shell_xml.c

@@ -614,6 +614,8 @@ static int process_startup(clish_shell_t *shell, clish_xmlnode_t *element,
 		"default_plugin");
 	char *default_shebang = clish_xmlnode_fetch_attr(element,
 		"default_shebang");
+	char *default_expand = clish_xmlnode_fetch_attr(element,
+		"default_expand");
 #ifdef LEGACY
 	char *lock = clish_xmlnode_fetch_attr(element, "lock");
 	char *interrupt = clish_xmlnode_fetch_attr(element, "interrupt");
@@ -645,6 +647,10 @@ static int process_startup(clish_shell_t *shell, clish_xmlnode_t *element,
 	if (default_shebang)
 		clish_shell__set_default_shebang(shell, default_shebang);
 
+	if (default_expand)
+		clish_shell__set_default_expand(shell,
+			(lub_string_nocasecmp(default_expand, "true") == 0));
+
 	if (timeout) {
 		unsigned int to = 0;
 		lub_conv_atoui(timeout, &to, 0);
@@ -684,6 +690,7 @@ error:
 	clish_xml_release(viewid);
 	clish_xml_release(default_plugin);
 	clish_xml_release(default_shebang);
+	clish_xml_release(default_expand);
 	clish_xml_release(timeout);
 #ifdef LEGACY
 	clish_xml_release(lock);
@@ -881,6 +888,7 @@ static int process_action(clish_shell_t *shell, clish_xmlnode_t *element,
 	char *lock = clish_xmlnode_fetch_attr(element, "lock");
 	char *interrupt = clish_xmlnode_fetch_attr(element, "interrupt");
 	char *interactive = clish_xmlnode_fetch_attr(element, "interactive");
+	char *expand = clish_xmlnode_fetch_attr(element, "expand");
 
 	clish_xmlnode_t *pelement = clish_xmlnode_parent(element);
 	char *pname = clish_xmlnode_get_all_name(pelement);
@@ -924,11 +932,16 @@ static int process_action(clish_shell_t *shell, clish_xmlnode_t *element,
 	if (interrupt && lub_string_nocasecmp(interrupt, "true") == 0)
 		clish_action__set_interrupt(action, BOOL_TRUE);
 
+	/* expand */
+	if (expand)
+		clish_action__set_expand(action, lub_tri_from_string(expand));
+
 	clish_xml_release(builtin);
 	clish_xml_release(shebang);
 	clish_xml_release(lock);
 	clish_xml_release(interrupt);
 	clish_xml_release(interactive);
+	clish_xml_release(expand);
 
 	return 0;
 }