Browse Source

Change plugin API

Serj Kalichev 10 years ago
parent
commit
0db777324b

+ 3 - 1
.gitignore

@@ -14,7 +14,8 @@
 /aux_scripts
 /config.log
 /config.status
-/stamp-h1
+/stamp-*
+/clish/stamp-*
 /Makefile
 /config.h
 /libtool
@@ -22,6 +23,7 @@
 /config.h.in
 /aclocal.m4
 /Makefile.in
+/clish/plugin_builtin.c
 
 # Debian files
 /build-stamp

+ 3 - 2
clish.xsd

@@ -523,8 +523,9 @@
 ********************************************************
 -->
     <xs:complexType name="plugin_t">
-        <xs:attribute name="file" type="xs:string" use="required"/>
-        <xs:attribute name="name" type="xs:string" use="optional"/>
+        <xs:attribute name="name" type="xs:string" use="required"/>
+        <xs:attribute name="alias" type="xs:string" use="optional"/>
+        <xs:attribute name="file" type="xs:string" use="optional"/>
     </xs:complexType>
 
 <!--

+ 5 - 5
clish/module.am

@@ -2,18 +2,18 @@
 lib_LTLIBRARIES += libclish.la
 
 libclish_la_SOURCES = \
-    clish/private.h
+	clish/plugin_builtin.c \
+	clish/private.h
 
 libclish_la_LDFLAGS = $(VERSION_INFO) @XML_LDFLAGS@
 libclish_la_CFLAGS = @XML_CFLAGS@ $(DEBUG_CFLAGS)
-libclish_la_LIBADD = \
-	liblub.la \
-	libtinyrl.la \
-	libkonf.la @XML_LIBS@
 libclish_la_DEPENDENCIES = \
 	liblub.la \
 	libtinyrl.la \
 	libkonf.la
+libclish_la_LIBADD = \
+	$(libclish_la_DEPENDENCIES) \
+	@XML_LIBS@
 
 nobase_include_HEADERS += \
 	clish/types.h \

+ 17 - 12
clish/plugin.h

@@ -4,6 +4,10 @@
 #ifndef _clish_plugin_h
 #define _clish_plugin_h
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include "lub/types.h"
 
 /* Symbol */
@@ -24,24 +28,20 @@ typedef struct clish_plugin_s clish_plugin_t;
 /* Plugin types */
 
 /* Name of init function within plugin */
-#define CLISH_PLUGIN_INIT_FNAME clish_plugin_init
-#define CLISH_PLUGIN_INIT_NAME "clish_plugin_init"
+#define CLISH_PLUGIN_INIT_FNAME(name) clish_plugin_##name##_init
+#define CLISH_PLUGIN_INIT_NAME_PREFIX "clish_plugin_"
+#define CLISH_PLUGIN_INIT_NAME_SUFFIX "_init"
 #define CLISH_PLUGIN_INIT_FUNC(name) int name(void *clish_shell, clish_plugin_t *plugin)
-#define CLISH_PLUGIN_INIT CLISH_PLUGIN_INIT_FUNC(CLISH_PLUGIN_INIT_FNAME)
-
-/* Name of fini function within plugin */
-#define CLISH_PLUGIN_FINI_FNAME clish_plugin_fini
-#define CLISH_PLUGIN_FINI_NAME "clish_plugin_fini"
-#define CLISH_PLUGIN_FINI_FUNC(name) int name(void *clish_shell, clish_plugin_t *plugin)
-#define CLISH_PLUGIN_FINI CLISH_PLUGIN_FINI_FUNC(CLISH_PLUGIN_FINI_FNAME)
+#define CLISH_PLUGIN_INIT(name) CLISH_PLUGIN_INIT_FUNC(CLISH_PLUGIN_INIT_FNAME(name))
 
+#define CLISH_PLUGIN_FINI(name) int name(void *clish_shell, clish_plugin_t *plugin)
 #define CLISH_PLUGIN_SYM(name) int name(void *clish_context, const char *script, char **out)
 #define CLISH_HOOK_ACCESS(name) int name(void *clish_context, const char *access)
 #define CLISH_HOOK_CONFIG(name) int name(void *clish_context)
 #define CLISH_HOOK_LOG(name) int name(void *clish_context, const char *line, int retcode)
 
 typedef CLISH_PLUGIN_INIT_FUNC(clish_plugin_init_t);
-typedef CLISH_PLUGIN_FINI_FUNC(clish_plugin_fini_t);
+typedef CLISH_PLUGIN_FINI(clish_plugin_fini_t);
 typedef CLISH_PLUGIN_SYM(clish_hook_action_fn_t);
 typedef CLISH_HOOK_ACCESS(clish_hook_access_fn_t);
 typedef CLISH_HOOK_CONFIG(clish_hook_config_fn_t);
@@ -50,6 +50,9 @@ typedef CLISH_HOOK_LOG(clish_hook_log_fn_t);
 /* Helpers */
 #define SYM_FN(TYPE,SYM) (*((clish_hook_##TYPE##_fn_t *)(clish_sym__get_func(SYM))))
 
+/* Create an array of builtin plugin's init functions */
+extern clish_plugin_init_t * clish_plugin_builtin_list[];
+
 /* Symbol */
 
 int clish_sym_compare(const void *first, const void *second);
@@ -69,7 +72,7 @@ int clish_sym_clone(clish_sym_t *dst, clish_sym_t *src);
 
 /* Plugin */
 
-clish_plugin_t *clish_plugin_new(const char *file, const char *alias);
+clish_plugin_t *clish_plugin_new(const char *name);
 void clish_plugin_free(clish_plugin_t *instance, void *userdata);
 int clish_plugin_load(clish_plugin_t *instance, void *userdata);
 clish_sym_t *clish_plugin_get_sym(clish_plugin_t *instance,
@@ -84,12 +87,14 @@ clish_sym_t *clish_plugin_add_hook(clish_plugin_t *instance,
 	void *func, const char *name, int type);
 clish_sym_t *clish_plugin_add_phook(clish_plugin_t *instance,
 	void *func, const char *name, int type);
+void clish_plugin_add_fini(clish_plugin_t *instance,
+	clish_plugin_fini_t *fini);
 void clish_plugin_dump(const clish_plugin_t *instance);
-void clish_plugin__set_name(clish_plugin_t *instance, const char *name);
 char *clish_plugin__get_name(const clish_plugin_t *instance);
 void clish_plugin__set_alias(clish_plugin_t *instance, const char *alias);
 char *clish_plugin__get_alias(const clish_plugin_t *instance);
 char *clish_plugin__get_pubname(const clish_plugin_t *instance);
+void clish_plugin__set_file(clish_plugin_t *instance, const char *file);
 char *clish_plugin__get_file(const clish_plugin_t *instance);
 void clish_plugin__set_conf(clish_plugin_t *instance, const char *conf);
 char *clish_plugin__get_conf(const clish_plugin_t *instance);

+ 56 - 20
clish/plugin/plugin.c

@@ -1,6 +1,11 @@
 /*
  * plugin.c
  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
 #include "private.h"
 #include "lub/string.h"
 #include "lub/list.h"
@@ -9,7 +14,9 @@
 #include <string.h>
 #include <stdio.h>
 #include <assert.h>
+#ifdef HAVE_DLFCN_H
 #include <dlfcn.h>
+#endif
 
 /**********************************************************
  * SYM functions                                          *
@@ -127,16 +134,16 @@ int clish_sym_clone(clish_sym_t *dst, clish_sym_t *src)
  **********************************************************/
 
 /*--------------------------------------------------------- */
-clish_plugin_t *clish_plugin_new(const char *file, const char *alias)
+clish_plugin_t *clish_plugin_new(const char *name)
 {
 	clish_plugin_t *this;
 
 	this = malloc(sizeof(*this));
 
-	this->file = lub_string_dup(file);
-	this->name = NULL;
+	this->name = lub_string_dup(name);
 	this->conf = NULL;
-	this->alias = lub_string_dup(alias);
+	this->alias = NULL;
+	this->file = NULL;
 	this->dlhan = NULL;
 	/* Initialise the list of symbols */
 	this->syms = lub_list_new(clish_sym_compare);
@@ -159,9 +166,9 @@ void clish_plugin_free(clish_plugin_t *this, void *userdata)
 	if (this->fini)
 		this->fini(userdata, this);
 
-	lub_string_free(this->file);
 	lub_string_free(this->name);
 	lub_string_free(this->alias);
+	lub_string_free(this->file);
 	lub_string_free(this->conf);
 
 	/* Free symbol list */
@@ -173,9 +180,10 @@ void clish_plugin_free(clish_plugin_t *this, void *userdata)
 		lub_list_node_free(iter);
 	}
 	lub_list_free(this->syms);
+#ifdef HAVE_DLFCN_H
 	if (this->dlhan)
 		dlclose(this->dlhan);
-
+#endif
 	free(this);
 }
 
@@ -230,6 +238,13 @@ clish_sym_t *clish_plugin_add_phook(clish_plugin_t *this,
 		name, type, BOOL_TRUE);
 }
 
+/*--------------------------------------------------------- */
+void clish_plugin_add_fini(clish_plugin_t *this,
+	clish_plugin_fini_t *fini)
+{
+	this->fini = fini;
+}
+
 /*--------------------------------------------------------- */
 clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name, int type)
 {
@@ -255,43 +270,57 @@ clish_sym_t *clish_plugin_get_sym(clish_plugin_t *this, const char *name, int ty
 int clish_plugin_load(clish_plugin_t *this, void *userdata)
 {
 	int res;
+	char *file = NULL; /* Plugin so file name */
+	char *init_name = NULL; /* Init function name */
 
 	if (!this)
 		return -1;
+	assert(this->name);
+
+#ifdef HAVE_DLFCN_H
+	if (this->file) {
+		file = lub_string_dup(this->file);
+	} else {
+		lub_string_cat(&file, "clish_plugin_");
+		lub_string_cat(&file, this->name);
+		lub_string_cat(&file, ".so");
+	}
 
 	/* Open dynamic library */
-	if (!(this->dlhan = dlopen(this->file, RTLD_NOW | RTLD_LOCAL))) {
+	this->dlhan = dlopen(file, RTLD_NOW | RTLD_LOCAL);
+	lub_string_free(file);
+	if (!this->dlhan) {
 		fprintf(stderr, "Error: Can't open plugin %s: %s\n",
-			this->file, dlerror());
+			this->name, dlerror());
 		return -1;
 	}
 
 	/* Get plugin init function */
-	this->init = (clish_plugin_init_t *)dlsym(this->dlhan, CLISH_PLUGIN_INIT_NAME);
+	lub_string_cat(&init_name, CLISH_PLUGIN_INIT_NAME_PREFIX);
+	lub_string_cat(&init_name, this->name);
+	lub_string_cat(&init_name, CLISH_PLUGIN_INIT_NAME_SUFFIX);
+	this->init = (clish_plugin_init_t *)dlsym(this->dlhan, init_name);
+	lub_string_free(init_name);
 	if (!this->init) {
 		fprintf(stderr, "Error: Can't get plugin %s init function: %s\n",
-			this->file, dlerror());
+			this->name, dlerror());
 		return -1;
 	}
 
-	/* Get plugin fini function */
-	this->fini = (clish_plugin_fini_t *)dlsym(this->dlhan, CLISH_PLUGIN_FINI_NAME);
+#else /* HAVE_DLFCN_H */
+	/* We have no any dl functions. */
+
+
+#endif /* HAVE_DLFCN_H */
 
 	/* Execute init function */
 	if ((res = this->init(userdata, this)))
 		fprintf(stderr, "Error: Plugin %s init retcode: %d\n",
-			this->file, res);
+			this->name, res);
 
 	return res;
 }
 
-/*--------------------------------------------------------- */
-void clish_plugin__set_name(clish_plugin_t *this, const char *name)
-{
-	lub_string_free(this->name);
-	this->name = lub_string_dup(name);
-}
-
 /*--------------------------------------------------------- */
 char *clish_plugin__get_name(const clish_plugin_t *this)
 {
@@ -317,6 +346,13 @@ char *clish_plugin__get_pubname(const clish_plugin_t *this)
 	return (this->alias ? this->alias : this->name);
 }
 
+/*--------------------------------------------------------- */
+void clish_plugin__set_file(clish_plugin_t *this, const char *file)
+{
+	lub_string_free(this->file);
+	this->file = lub_string_dup(file);
+}
+
 /*--------------------------------------------------------- */
 char *clish_plugin__get_file(const clish_plugin_t *this)
 {

+ 0 - 1
clish/plugin/plugin_dump.c

@@ -56,7 +56,6 @@ void clish_plugin_dump(const clish_plugin_t *this)
 	lub_dump_printf("name  : %s\n", this->name);
 	lub_dump_printf("alias : %s\n", this->alias);
 	lub_dump_printf("conf  : %s\n", this->conf);
-	lub_dump_printf("file  : %s\n", this->file);
 	lub_dump_printf("dlhan : %p\n", this->dlhan);
 	lub_dump_printf("init  : %p\n", this->init);
 	lub_dump_printf("fini  : %p\n", this->fini);

+ 2 - 2
clish/plugin/private.h

@@ -18,9 +18,9 @@ struct clish_sym_s {
 };
 
 struct clish_plugin_s {
-	char *file; /* Plugin file name. Must be unique. */
-	char *name; /* Plugin name defined by plugin itself. */
+	char *name; /* Plugin name. */
 	char *alias; /* User defined plugin name. Can be used in builtin ref. */
+	char *file; /* Shared object file name. */
 	char *conf; /* The content of <PLUGIN>...</PLUGIN> */
 	lub_list_t *syms; /* List of plugin symbols */
 	void *dlhan; /* Handler of dlopen() */

+ 14 - 0
clish/plugin_builtin.c.in

@@ -0,0 +1,14 @@
+/*
+ * plugin_builtin.c.in
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <stdlib.h>
+#include "clish/plugin.h"
+
+/* The array of builtin plugin's filled by configure script. */
+clish_plugin_init_t * clish_plugin_builtin_list[] = {@CLISH_PLUGIN_BUILTIN_LIST@ NULL};
+

+ 6 - 1
clish/shell/shell_expat.c

@@ -310,6 +310,7 @@ clish_xmldoc_t *clish_xmldoc_read(const char *filename)
 	int fd;
 	char *buffer;
 	XML_Parser parser;
+	int rb;
 
 	doc = malloc(sizeof(clish_xmldoc_t));
 	if (!doc)
@@ -330,7 +331,11 @@ clish_xmldoc_t *clish_xmldoc_read(const char *filename)
 		goto error_open;
 	fstat(fd, &sb);
 	buffer = malloc(sb.st_size+1);
-	read(fd, buffer, sb.st_size);
+	rb = read(fd, buffer, sb.st_size);
+	if (rb < 0) {
+		close(fd);
+		goto error_parse;
+	}
 	buffer[sb.st_size] = 0;
 	close(fd);
 

+ 13 - 5
clish/shell/shell_xml.c

@@ -19,7 +19,7 @@
 #include <dirent.h>
 
 /* Default hooks */
-#define CLISH_PLUGIN_DEFAULT "clish_plugin_default.so"
+#define CLISH_PLUGIN_DEFAULT "clish_plugin_clish.so"
 const char* clish_plugin_default_hook[] = {
 	NULL,
 	"clish_script@clish",
@@ -155,7 +155,7 @@ int clish_shell_load_scheme(clish_shell_t *this, const char *xml_path)
 	/* Load default plugin */
 	if (this->default_plugin) {
 		clish_plugin_t *plugin;
-		plugin = clish_plugin_new(CLISH_PLUGIN_DEFAULT, "clish");
+		plugin = clish_plugin_new("clish");
 		lub_list_add(this->plugins, plugin);
 		/* Default hooks */
 		for (i = 0; i < CLISH_SYM_TYPE_MAX; i++) {
@@ -1195,18 +1195,25 @@ process_plugin(clish_shell_t *shell, clish_xmlnode_t* element, void *parent)
 	clish_plugin_t *plugin;
 	char *file = clish_xmlnode_fetch_attr(element, "file");
 	char *name = clish_xmlnode_fetch_attr(element, "name");
+	char *alias = clish_xmlnode_fetch_attr(element, "alias");
 	int res = -1;
 	char *text;
 
 	/* Check syntax */
-	if (!file) {
-		fprintf(stderr, CLISH_XML_ERROR_ATTR("file"));
+	if (!name) {
+		fprintf(stderr, CLISH_XML_ERROR_ATTR("name"));
 		goto error;
 	}
 
-	plugin = clish_plugin_new(file, name); /* Really - the name is alias */
+	plugin = clish_plugin_new(name);
 	lub_list_add(shell->plugins, plugin);
 
+	if (alias && *alias)
+		clish_plugin__set_alias(plugin, alias);
+
+	if (file && *file)
+		clish_plugin__set_file(plugin, file);
+
 	/* Get PLUGIN body content */
 	text = clish_xmlnode_get_all_content(element);
 	if (text && *text)
@@ -1218,6 +1225,7 @@ process_plugin(clish_shell_t *shell, clish_xmlnode_t* element, void *parent)
 error:
 	clish_xml_release(file);
 	clish_xml_release(name);
+	clish_xml_release(alias);
 
 	return res;
 }

+ 9 - 4
configure.ac

@@ -534,12 +534,17 @@ AC_CHECK_FUNCS(chroot, [],
 ################################
 # Check for dlopen
 ################################
+CLISH_PLUGIN_BUILTIN_LIST=
 AC_CHECK_HEADERS(dlfcn.h, [
         AC_SEARCH_LIBS([dlopen], [dl dld], [], [
-          AC_MSG_WARN([unable to find the dlopen() function])
+          AC_MSG_ERROR([unable to find the dlopen() function])
         ])
-    ],
-    AC_MSG_WARN([dlfcn.h not found: the dl operations is not supported]))
+    ],[
+          AC_MSG_WARN([dlfcn.h not found: the dl operations is not supported])
+          CLISH_PLUGIN_BUILTIN_LIST="$CLISH_PLUGIN_BUILTIN_LIST clish_clish_plugin_init,"
+    ])
+AC_SUBST([CLISH_PLUGIN_BUILTIN_LIST])
+AC_CONFIG_FILES([clish/plugin_builtin.c])
 
-AC_CONFIG_FILES(Makefile)
+AC_CONFIG_FILES([Makefile])
 AC_OUTPUT

+ 1 - 4
plugins/clish/builtin_init.c

@@ -9,11 +9,8 @@
 
 /*----------------------------------------------------------- */
 /* Initialize internal pseudo-plugin */
-CLISH_PLUGIN_INIT
+CLISH_PLUGIN_INIT(clish)
 {
-	/* Set plugin name */
-	clish_plugin__set_name(plugin, "clish");
-
 	/* Add hooks */
 	clish_plugin_add_phook(plugin, clish_hook_access,
 		"clish_hook_access", CLISH_SYM_TYPE_ACCESS);

+ 1 - 1
plugins/lua/plugin_fini.c

@@ -2,7 +2,7 @@
 
 #include "private.h"
 
-CLISH_PLUGIN_FINI
+CLISH_PLUGIN_FINI(clish_plugin_lua_fini)
 {
 	lua_State *L = clish_shell__del_udata(clish_shell, LUA_UDATA);
 

+ 4 - 5
plugins/lua/plugin_init.c

@@ -1,9 +1,9 @@
-#include <lub/ini.h>
-#include <lub/string.h>
+#include "lub/ini.h"
+#include "lub/string.h"
 
 #include "private.h"
 
-CLISH_PLUGIN_INIT
+CLISH_PLUGIN_INIT(lua)
 {
 	lub_ini_t *ini;
 	char *conf = clish_plugin__get_conf(plugin);
@@ -19,8 +19,7 @@ CLISH_PLUGIN_INIT
 	if(clish_plugin_init_lua(clish_shell))
 		return (-1);
 
-	clish_plugin__set_name(plugin, LUA_PLUGIN_NAME);
-
+	clish_plugin_add_fini(plugin, clish_plugin_lua_fini);
 	clish_plugin_add_sym(plugin, clish_plugin_lua_action, "lua");
 
 	return 0;

+ 1 - 1
plugins/lua/private.h

@@ -9,12 +9,12 @@
 
 #define LUA_UDATA "lua_state"
 #define LUA_SCRIPTS_DIR "scripts_dir"
-#define LUA_PLUGIN_NAME "lua"
 
 extern char *scripts_path;
 void l_print_error(lua_State *, const char *, const char *, int);
 int clish_plugin_init_lua(clish_shell_t *shell);
 
 CLISH_PLUGIN_SYM(clish_plugin_lua_action);
+CLISH_PLUGIN_FINI(clish_plugin_lua_fini);
 
 #endif /* _PLUGIN_H_ */