From bb03b9c0814c32395856df1015ab18b04c58c62c Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Sun, 1 Nov 2020 22:42:49 +0000 Subject: [PATCH] Let mosquitto_ctrl load external modules. Also provide an example. --- apps/mosquitto_ctrl/Makefile | 14 +++++++--- apps/mosquitto_ctrl/example.c | 38 ++++++++++++++++++++++++++++ apps/mosquitto_ctrl/mosquitto_ctrl.c | 29 ++++++++++++++++----- apps/mosquitto_ctrl/mosquitto_ctrl.h | 6 +++++ 4 files changed, 78 insertions(+), 9 deletions(-) create mode 100644 apps/mosquitto_ctrl/example.c diff --git a/apps/mosquitto_ctrl/Makefile b/apps/mosquitto_ctrl/Makefile index 486c6db0..08e2b3db 100644 --- a/apps/mosquitto_ctrl/Makefile +++ b/apps/mosquitto_ctrl/Makefile @@ -22,16 +22,21 @@ OBJS= mosquitto_ctrl.o \ options.o \ password_mosq.o +EXAMPLE_OBJS= example.o + ifeq ($(WITH_TLS),yes) ifeq ($(WITH_CJSON),yes) -TARGET:=mosquitto_ctrl +TARGET:=mosquitto_ctrl mosquitto_ctrl_example.so endif endif all : $(TARGET) mosquitto_ctrl : ${OBJS} - ${CROSS_COMPILE}${CC} ${APP_LDFLAGS} $^ -o $@ $(PASSWD_LDADD) $(LIBMOSQ) -lcjson + ${CROSS_COMPILE}${CC} ${APP_LDFLAGS} $^ -o $@ $(PASSWD_LDADD) $(LIBMOSQ) -lcjson -ldl + +mosquitto_ctrl_example.so : ${EXAMPLE_OBJS} + $(CROSS_COMPILE)$(CC) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) $(PLUGIN_LDFLAGS) -fPIC -shared $< -o $@ mosquitto_ctrl.o : mosquitto_ctrl.c mosquitto_ctrl.h ${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ @@ -51,6 +56,9 @@ dynsec_group.o : dynsec_group.c mosquitto_ctrl.h dynsec_role.o : dynsec_role.c mosquitto_ctrl.h ${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ +example.o : example.c mosquitto_ctrl.h + ${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ + get_password.o : ../mosquitto_passwd/get_password.c ../mosquitto_passwd/get_password.h ${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(APP_CPPFLAGS) $(APP_CFLAGS) -c $< -o $@ @@ -77,7 +85,7 @@ uninstall : -rm -f "${DESTDIR}${prefix}/bin/mosquitto_ctrl" clean : - -rm -f *.o mosquitto_ctrl *.gcda *.gcno + -rm -f *.o mosquitto_ctrl *.gcda *.gcno *.so reallyclean : clean -rm -rf *.orig *.db diff --git a/apps/mosquitto_ctrl/example.c b/apps/mosquitto_ctrl/example.c new file mode 100644 index 00000000..f8e12086 --- /dev/null +++ b/apps/mosquitto_ctrl/example.c @@ -0,0 +1,38 @@ +/* +Copyright (c) 2020 Roger Light + +All rights reserved. This program and the accompanying materials +are made available under the terms of the Eclipse Public License v1.0 +and Eclipse Distribution License v1.0 which accompany this distribution. + +The Eclipse Public License is available at + http://www.eclipse.org/legal/epl-v10.html +and the Eclipse Distribution License is available at + http://www.eclipse.org/org/documents/edl-v10.php. + +Contributors: + Roger Light - initial implementation and documentation. +*/ +#include +#include +#include +#include + +#include "mosquitto_ctrl.h" + +void ctrl_help(void) +{ + printf("\nExample module\n"); + printf("==============\n"); + printf(" mosquitto_ctrl example help\n"); +} + +int ctrl_main(int argc, char *argv[], struct mosq_ctrl *ctrl) +{ + if(!strcasecmp(argv[0], "help")){ + ctrl_help(); + return -1; + }else{ + return MOSQ_ERR_INVAL; + } +} diff --git a/apps/mosquitto_ctrl/mosquitto_ctrl.c b/apps/mosquitto_ctrl/mosquitto_ctrl.c index fe511456..1fa6b5e5 100644 --- a/apps/mosquitto_ctrl/mosquitto_ctrl.c +++ b/apps/mosquitto_ctrl/mosquitto_ctrl.c @@ -22,6 +22,7 @@ Contributors: #include #include +#include "lib_load.h" #include "mosquitto.h" #include "mosquitto_ctrl.h" @@ -47,7 +48,10 @@ void print_usage(void) int main(int argc, char *argv[]) { struct mosq_ctrl ctrl; - int rc; + int rc = MOSQ_ERR_SUCCESS; + FUNC_ctrl_main ctrl_main = NULL; + void *lib = NULL; + char lib_name[200]; if(argc == 1){ print_usage(); @@ -67,9 +71,25 @@ int main(int argc, char *argv[]) print_usage(); return 1; } - + + /* In built modules */ if(!strcasecmp(argv[0], "dynsec")){ - rc = dynsec__main(argc-1, &argv[1], &ctrl); + ctrl_main = dynsec__main; + }else{ + /* Attempt external module */ + snprintf(lib_name, sizeof(lib_name), "mosquitto_ctrl_%s.so", argv[0]); + lib = LIB_LOAD(lib_name); + if(lib){ + ctrl_main = (FUNC_ctrl_main)LIB_SYM(lib, "ctrl_main"); + if(ctrl_main == NULL){ + fprintf(stderr, "Error: Module '%s' not supported.\n", argv[0]); + rc = MOSQ_ERR_NOT_SUPPORTED; + } + } + } + + if(ctrl_main){ + rc = ctrl_main(argc-1, &argv[1], &ctrl); if(rc < 0){ /* Usage print */ rc = 0; @@ -80,9 +100,6 @@ int main(int argc, char *argv[]) }else{ fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc)); } - }else{ - fprintf(stderr, "Error: Module '%s' not supported.\n", argv[0]); - rc = MOSQ_ERR_NOT_SUPPORTED; } client_config_cleanup(&ctrl.cfg); diff --git a/apps/mosquitto_ctrl/mosquitto_ctrl.h b/apps/mosquitto_ctrl/mosquitto_ctrl.h index d202a225..80bb11c7 100644 --- a/apps/mosquitto_ctrl/mosquitto_ctrl.h +++ b/apps/mosquitto_ctrl/mosquitto_ctrl.h @@ -73,6 +73,8 @@ struct mosq_ctrl { void *userdata; }; +typedef int (*FUNC_ctrl_main)(int argc, char *argv[], struct mosq_ctrl *ctrl); + void init_config(struct mosq_config *cfg); int ctrl_config_parse(struct mosq_config *cfg, int *argc, char **argv[]); int client_config_load(struct mosq_config *cfg); @@ -109,4 +111,8 @@ int dynsec_role__list_all(int argc, char *argv[], cJSON *j_command); int dynsec_role__add_acl(int argc, char *argv[], cJSON *j_command); int dynsec_role__remove_acl(int argc, char *argv[], cJSON *j_command); +/* Functions to implement as an external module: */ +void ctrl_help(void); +int ctrl_main(int argc, char *argv[], struct mosq_ctrl *ctrl); + #endif