Browse Source

Implement dry-run

Serj Kalichev 11 years ago
parent
commit
4d670316e3

+ 6 - 2
bin/clish.c

@@ -63,6 +63,7 @@ int main(int argc, char **argv)
 	bool_t utf8 = BOOL_FALSE;
 	bool_t bit8 = BOOL_FALSE;
 	bool_t log = BOOL_FALSE;
+	bool_t dryrun = BOOL_FALSE;
 	const char *xml_path = getenv("CLISH_PATH");
 	const char *view = getenv("CLISH_VIEW");
 	const char *viewid = getenv("CLISH_VIEWID");
@@ -158,7 +159,7 @@ int main(int argc, char **argv)
 			log = BOOL_TRUE;
 			break;
 		case 'd':
-			/* TODO: clish_dryrun_callback; */
+			dryrun = BOOL_TRUE;
 			break;
 		case 'x':
 			xml_path = optarg;
@@ -171,7 +172,7 @@ int main(int argc, char **argv)
 			break;
 		case 'k':
 			lockless = BOOL_TRUE;
-			/* TODO: set clish_dryrun_callback; */
+			dryrun = BOOL_TRUE;
 			my_hooks.config_fn = NULL;
 			break;
 		case 't':
@@ -264,6 +265,9 @@ int main(int argc, char **argv)
 	/* Set logging */
 	if (log)
 		clish_shell__set_log(shell, log);
+	/* Set dry-run */
+	if (dryrun)
+		clish_shell__set_dryrun(shell, dryrun);
 	/* Set idle timeout */
 	if (istimeout)
 		clish_shell__set_timeout(shell, timeout);

+ 8 - 2
clish/plugin.h

@@ -4,6 +4,8 @@
 #ifndef _clish_plugin_h
 #define _clish_plugin_h
 
+#include "lub/types.h"
+
 /* Symbol types */
 
 typedef struct clish_sym_s clish_sym_t;
@@ -33,15 +35,19 @@ void clish_sym__set_func(clish_sym_t *instance, clish_plugin_fn_t *func);
 clish_plugin_fn_t *clish_sym__get_func(clish_sym_t *instance);
 void clish_sym__set_name(clish_sym_t *instance, const char *name);
 char *clish_sym__get_name(clish_sym_t *instance);
+void clish_sym__set_permanent(clish_sym_t *instance, bool_t permanent);
+bool_t clish_sym__get_permanent(clish_sym_t *instance);
 
 /* Plugin */
 
 clish_plugin_t *clish_plugin_new(const char *name, const char *file);
 void clish_plugin_free(clish_plugin_t *instance);
 void *clish_plugin_load(clish_plugin_t *instance);
-clish_plugin_fn_t *clish_plugin_get_sym(clish_plugin_t *instance,
+clish_sym_t *clish_plugin_get_sym(clish_plugin_t *instance,
 	const char *name);
-int clish_plugin_add_sym(clish_plugin_t *instance,
+clish_sym_t *clish_plugin_add_sym(clish_plugin_t *instance,
+	clish_plugin_fn_t *func, const char *name);
+clish_sym_t *clish_plugin_add_psym(clish_plugin_t *instance,
 	clish_plugin_fn_t *func, const char *name);
 void clish_plugin_dump(const clish_plugin_t *instance);
 char *clish_plugin__get_name(const clish_plugin_t *instance);

+ 33 - 6
clish/plugin/plugin.c

@@ -32,6 +32,7 @@ clish_sym_t *clish_sym_new(const char *name, clish_plugin_fn_t *func)
 	this = malloc(sizeof(*this));
 	this->name = lub_string_dup(name);
 	this->func = func;
+	this->permanent = BOOL_FALSE;
 
 	return this;
 }
@@ -57,6 +58,18 @@ clish_plugin_fn_t *clish_sym__get_func(clish_sym_t *this)
 	return this->func;
 }
 
+/*--------------------------------------------------------- */
+void clish_sym__set_permanent(clish_sym_t *this, bool_t permanent)
+{
+	this->permanent = permanent;
+}
+
+/*--------------------------------------------------------- */
+bool_t clish_sym__get_permanent(clish_sym_t *this)
+{
+	return this->permanent;
+}
+
 /*--------------------------------------------------------- */
 void clish_sym__set_name(clish_sym_t *this, const char *name)
 {
@@ -123,23 +136,37 @@ void clish_plugin_free(clish_plugin_t *this)
 }
 
 /*--------------------------------------------------------- */
-int clish_plugin_add_sym(clish_plugin_t *this,
+clish_sym_t *clish_plugin_add_sym(clish_plugin_t *this,
 	clish_plugin_fn_t *func, const char *name)
 {
 	clish_sym_t *sym;
 
 	if (!name || !func)
-		return -1;
+		return NULL;
 
 	if (!(sym = clish_sym_new(name, func)))
-		return -1;
+		return NULL;
 	lub_list_add(this->syms, sym);
 
-	return 0;
+	return sym;
+}
+
+/*--------------------------------------------------------- */
+/* Add permanent symbol (can't be turned off by dry-run) */
+clish_sym_t *clish_plugin_add_psym(clish_plugin_t *this,
+	clish_plugin_fn_t *func, const char *name)
+{
+	clish_sym_t *sym;
+
+	if (!(sym = clish_plugin_add_sym(this, func, name)))
+		return NULL;
+	clish_sym__set_permanent(sym, BOOL_TRUE);
+
+	return sym;
 }
 
 /*--------------------------------------------------------- */
-clish_plugin_fn_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name)
+clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name)
 {
 	lub_list_node_t *iter;
 	clish_sym_t *sym;
@@ -151,7 +178,7 @@ clish_plugin_fn_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name)
 		sym = (clish_sym_t *)lub_list_node__get_data(iter);
 		res = strcmp(clish_sym__get_name(sym), name);
 		if (!res)
-			return clish_sym__get_func(sym);
+			return sym;
 		if (res > 0) /* No chances to find name */
 			break;
 	}

+ 1 - 0
clish/plugin/private.h

@@ -12,6 +12,7 @@
 struct clish_sym_s {
 	char *name; /* Symbol name */
 	clish_plugin_fn_t *func; /* Function address */
+	bool_t permanent; /* If permanent the dry-run can't switch off it */
 };
 
 struct clish_plugin_s {

+ 2 - 0
clish/shell.h

@@ -329,6 +329,8 @@ int clish_shell__save_history(const clish_shell_t *instance, const char *fname);
 int clish_shell__restore_history(clish_shell_t *instance, const char *fname);
 void clish_shell__stifle_history(clish_shell_t *instance, unsigned int stifle);
 struct passwd *clish_shell__get_user(clish_shell_t *instance);
+void clish_shell__set_dryrun(clish_shell_t *instance, bool_t dryrun);
+bool_t clish_shell__get_dryrun(const clish_shell_t *instance);
 
 /* Plugin functions */
 int clish_shell_load_plugins(clish_shell_t *instance);

+ 4 - 2
clish/shell/private.h

@@ -66,9 +66,12 @@ struct clish_shell_s {
 	char *lockfile;
 	char *default_shebang;
 	char *fifo_name; /* The name of temporary fifo file. */
+	struct passwd *user; /* Current user information */
+
+	/* Boolean flags */
 	bool_t interactive; /* Is shell interactive. */
 	bool_t log; /* If command logging is enabled */
-	struct passwd *user; /* Current user information */
+	bool_t dryrun; /* Is this a dry-running */
 
 	/* Plugins and symbols */
 	lub_list_t *plugins; /* List of plugins */
@@ -136,5 +139,4 @@ int clish_shell_timeout_fn(tinyrl_t *tinyrl);
 int clish_shell_keypress_fn(tinyrl_t *tinyrl, int key);
 
 /* Internal plugin symbols */
-CLISH_PLUGIN_SYM(clish_dryrun);
 CLISH_PLUGIN_SYM(clish_script);

+ 15 - 0
clish/shell/shell_execute.c

@@ -198,9 +198,12 @@ int clish_shell_exec_action(clish_context_t *context, char **out)
 	char *script;
 	clish_plugin_fn_t *func = NULL;
 	const clish_action_t *action = context->action;
+	clish_shell_t *shell = context->shell;
 
 	if (!(sym = clish_action__get_builtin(action)))
 		return 0;
+	if (shell->dryrun && !clish_sym__get_permanent(sym))
+		return 0;
 	if (!(func = clish_sym__get_func(sym)))
 		return -1;
 	script = clish_shell_expand(clish_action__get_script(action), SHELL_VAR_ACTION, context);
@@ -257,4 +260,16 @@ bool_t clish_shell__get_log(const clish_shell_t *this)
 	return this->log;
 }
 
+/*-------------------------------------------------------- */
+void clish_shell__set_dryrun(clish_shell_t *this, bool_t dryrun)
+{
+	this->dryrun = dryrun;
+}
+
+/*-------------------------------------------------------- */
+bool_t clish_shell__get_dryrun(const clish_shell_t *this)
+{
+	return this->dryrun;
+}
+
 /*----------------------------------------------------------- */

+ 8 - 9
clish/shell/shell_internal.c

@@ -188,15 +188,14 @@ CLISH_PLUGIN_SYM(clish_wdog)
 /* Initialize internal pseudo-plugin */
 CLISH_PLUGIN_INIT
 {
-	clish_plugin_add_sym(plugin, clish_close, "clish_close");
-	clish_plugin_add_sym(plugin, clish_overview, "clish_overview");
-	clish_plugin_add_sym(plugin, clish_source, "clish_source");
-	clish_plugin_add_sym(plugin, clish_source_nostop, "clish_source_nostop");
-	clish_plugin_add_sym(plugin, clish_history, "clish_history");
-	clish_plugin_add_sym(plugin, clish_nested_up, "clish_nested_up");
-	clish_plugin_add_sym(plugin, clish_nop, "clish_nop");
-	clish_plugin_add_sym(plugin, clish_wdog, "clish_wdog");
-	clish_plugin_add_sym(plugin, clish_dryrun, "clish_dryrun");
+	clish_plugin_add_psym(plugin, clish_close, "clish_close");
+	clish_plugin_add_psym(plugin, clish_overview, "clish_overview");
+	clish_plugin_add_psym(plugin, clish_source, "clish_source");
+	clish_plugin_add_psym(plugin, clish_source_nostop, "clish_source_nostop");
+	clish_plugin_add_psym(plugin, clish_history, "clish_history");
+	clish_plugin_add_psym(plugin, clish_nested_up, "clish_nested_up");
+	clish_plugin_add_psym(plugin, clish_nop, "clish_nop");
+	clish_plugin_add_psym(plugin, clish_wdog, "clish_wdog");
 	clish_plugin_add_sym(plugin, clish_script, "clish_script");
 
 	return 0;

+ 1 - 0
clish/shell/shell_new.c

@@ -75,6 +75,7 @@ static void clish_shell_init(clish_shell_t * this,
 	this->fifo_name = NULL;
 	this->interactive = BOOL_TRUE; /* The interactive shell by default. */
 	this->log = BOOL_FALSE; /* Disable logging by default */
+	this->dryrun = BOOL_FALSE; /* Disable dry-run by default */
 	this->user = lub_db_getpwuid(getuid()); /* Get user information */
 
 	/* Create internal ptypes and params */

+ 11 - 10
clish/shell/shell_plugin.c

@@ -65,11 +65,11 @@ static clish_plugin_t *plugin_by_name(clish_shell_t *this, const char *name)
  * mysym@plugin1
  * The symbols with prefix will be resolved using specified plugin only.
  */
-static clish_plugin_fn_t *plugins_find_sym(clish_shell_t *this, const char *name)
+static clish_sym_t *plugins_find_sym(clish_shell_t *this, const char *name)
 {
 	lub_list_node_t *iter;
 	clish_plugin_t *plugin;
-	clish_plugin_fn_t *func = NULL;
+	clish_sym_t *sym = NULL;
 	/* To parse command name */
 	char *saveptr;
 	const char *delim = "@";
@@ -90,19 +90,19 @@ static clish_plugin_fn_t *plugins_find_sym(clish_shell_t *this, const char *name
 		plugin = plugin_by_name(this, plugin_name);
 		if (!plugin)
 			goto end;
-		func = clish_plugin_get_sym(plugin, cmdn);
+		sym = clish_plugin_get_sym(plugin, cmdn);
 	} else {
 		/* Iterate all plugins */
 		for(iter = lub_list__get_head(this->plugins);
 			iter; iter = lub_list_node__get_next(iter)) {
 			plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
-			if ((func = clish_plugin_get_sym(plugin, cmdn)))
+			if ((sym = clish_plugin_get_sym(plugin, cmdn)))
 				break;
 		}
 	}
 end:
 	lub_string_free(str);
-	return func;
+	return sym;
 }
 
 /*--------------------------------------------------------- */
@@ -156,23 +156,24 @@ clish_sym_t *clish_shell_add_unresolved_sym(clish_shell_t *this,
 /* Link unresolved symbols */
 int clish_shell_link_plugins(clish_shell_t *this)
 {
-	clish_sym_t *sym;
+	clish_sym_t *sym, *plugin_sym;
 	lub_list_node_t *iter;
 	char *sym_name = NULL;
-	clish_plugin_fn_t *fn = NULL;
 
 	/* Iterate elements */
 	for(iter = lub_list__get_head(this->syms);
 		iter; iter = lub_list_node__get_next(iter)) {
 		sym = (clish_sym_t *)lub_list_node__get_data(iter);
 		sym_name = clish_sym__get_name(sym);
-		fn = plugins_find_sym(this, sym_name);
-		if (!fn) {
+		plugin_sym = plugins_find_sym(this, sym_name);
+		if (!plugin_sym) {
 			fprintf(stderr, "Error: Can't resolve symbol %s.\n",
 				sym_name);
 			return -1;
 		}
-		clish_sym__set_func(sym, fn);
+		/* Copy symbol attributes */
+		clish_sym__set_func(sym, clish_sym__get_func(plugin_sym));
+		clish_sym__set_permanent(sym, clish_sym__get_permanent(plugin_sym));
 	}
 
 	return 0;

+ 2 - 14
clish/shell/shell_script.c

@@ -1,7 +1,7 @@
 /*
- * clish_script_callback.c
+ * shell_script.c
  *
- * Callback hook to action a shell script.
+ * Function to execute a shell script.
  */
 
 #include "private.h"
@@ -159,15 +159,3 @@ CLISH_PLUGIN_SYM(clish_script)
 }
 
 /*--------------------------------------------------------- */
-CLISH_PLUGIN_SYM(clish_dryrun)
-{
-#ifdef DEBUG
-	fprintf(stderr, "DRY-RUN: %s\n", script);
-#endif /* DEBUG */
-	if (out)
-		*out = NULL;
-
-	return 0;
-}
-
-/*--------------------------------------------------------- */