diff --git a/Makefile b/Makefile index ce88543..0eb4cfa 100755 --- a/Makefile +++ b/Makefile @@ -68,11 +68,8 @@ XLDFLAGS += $(LIBWEBSOCKETS_DIR)/lib/libwebsockets.a CURL_DIR = $(FRAMEWORK_BUILD_DIR)/curl ifneq ($(wildcard $(CURL_DIR)),) INC_DIRS += $(CURL_DIR)/include -XLDFLAGS += $(CURL_DIR)/lib/libcurl.a -else -# Commands to run if the directory does not exist -XLDFLAGS += -lcurl endif +XLDFLAGS += -ldl # UT Control library Requirements SRC_DIRS += ${TOP_DIR}/src @@ -93,16 +90,6 @@ ifeq ($(TARGET),arm) #CC := arm-rdk-linux-gnueabi-gcc -mthumb -mfpu=vfp -mcpu=cortex-a9 -mfloat-abi=soft -mabi=aapcs-linux -mno-thumb-interwork -ffixed-r8 -fomit-frame-pointer # CFLAGS will be overriden by Caller as required INC_DIRS += $(UT_DIR)/sysroot/usr/include -XLDFLAGS += $(OPENSSL_LIB_DIR)/libssl.a $(OPENSSL_LIB_DIR)/libcrypto.a -ldl -else -#linux case -# Check if the directory exists -ifneq ($(wildcard $(OPENSSL_LIB_DIR)),) -XLDFLAGS += $(OPENSSL_LIB_DIR)/libssl.a $(OPENSSL_LIB_DIR)/libcrypto.a -ldl -else -# Commands to run if the directory does not exist -XLDFLAGS += -lssl -lcrypto -endif endif # Defaults for target linux @@ -150,6 +137,7 @@ list: @$(ECHOE) ${YELLOW}SRC_DIRS:${NC} ${SRC_DIRS} @$(ECHOE) ${YELLOW}CFLAGS:${NC} ${CFLAGS} @$(ECHOE) ${YELLOW}XLDFLAGS:${NC} ${XLDFLAGS} + @$(ECHOE) ${YELLOW}XCFLAGS:${NC} ${XCFLAGS} @$(ECHOE) ${YELLOW}TARGET_LIB:${NC} ${TARGET_LIB} clean: diff --git a/configure.sh b/configure.sh index ad4866a..097df72 100755 --- a/configure.sh +++ b/configure.sh @@ -288,13 +288,13 @@ build_curl() mkdir -p ${CURL_BUILD_DIR} if [ "$TARGET" = "arm" ]; then # For arm - ./configure CPPFLAGS="-I${OPENSSL_BUILD_DIR}/include" LDFLAGS="-L${OPENSSL_BUILD_DIR}/lib" --prefix=${CURL_BUILD_DIR} --host=arm --with-ssl=${OPENSSL_BUILD_DIR} --with-pic --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl --without-zlib + ./configure CPPFLAGS="-I${OPENSSL_BUILD_DIR}/include" LDFLAGS="-L${OPENSSL_BUILD_DIR}/lib" --prefix=${CURL_BUILD_DIR} --host=arm-none-linux-gnu --with-ssl=${OPENSSL_BUILD_DIR} --enable-shared --enable-static --with-pic --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl --without-zlib else # For linux if [ "$OPENSSL_IS_SYSTEM_INSTALLED" -eq 1 ]; then - ./configure --prefix=${CURL_BUILD_DIR} --with-ssl --without-zlib --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl + ./configure --prefix=${CURL_BUILD_DIR} --with-ssl --without-zlib --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl --enable-shared --enable-static else - ./configure CPPFLAGS="-I${OPENSSL_BUILD_DIR}/include" LDFLAGS="-L${OPENSSL_BUILD_DIR}/lib" --prefix=${CURL_BUILD_DIR} --with-ssl=${OPENSSL_BUILD_DIR} --with-pic --without-zlib --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl + ./configure CPPFLAGS="-I${OPENSSL_BUILD_DIR}/include" LDFLAGS="-L${OPENSSL_BUILD_DIR}/lib" --prefix=${CURL_BUILD_DIR} --with-ssl=${OPENSSL_BUILD_DIR} --with-pic --without-zlib --without-libpsl --without-libidn2 --disable-docs --disable-libcurl-option --disable-alt-svc --disable-headers-api --disable-hsts --without-libgsasl --enable-shared --enable-static fi fi make $@; make $@ install diff --git a/src/ut_kvp.c b/src/ut_kvp.c index 7fef9fa..0b2b1d8 100644 --- a/src/ut_kvp.c +++ b/src/ut_kvp.c @@ -24,6 +24,7 @@ #include #include #include +#include /* Application Includes */ #include @@ -62,6 +63,60 @@ static struct fy_node* process_include(const char *filename, int depth, struct f static void merge_nodes(struct fy_node *mainNode, struct fy_node *includeNode); static void remove_include_keys(struct fy_node *node); +// Typedefs for curl function pointers +typedef CURL* (*curl_easy_init_t)(void); +typedef CURLcode (*curl_easy_setopt_t)(CURL *, CURLoption, ...); +typedef CURLcode (*curl_easy_perform_t)(CURL *); +typedef CURLcode (*curl_easy_getinfo_t)(CURL *, CURLINFO, ...); +typedef void (*curl_easy_cleanup_t)(CURL *); +typedef const char* (*curl_easy_strerror_t)(CURLcode); + +// Function pointers for curl functions +static curl_easy_init_t kvp_curl_easy_init; +static curl_easy_setopt_t kvp_curl_easy_setopt; +static curl_easy_perform_t kvp_curl_easy_perform; +static curl_easy_getinfo_t kvp_curl_easy_getinfo; +static curl_easy_cleanup_t kvp_curl_easy_cleanup; +static curl_easy_strerror_t kvp_curl_easy_strerror; +static void *curl_lib = NULL; + +int init_curl_symbols() +{ + UT_LOG_DEBUG("Initializing curl symbols from %s", "libcurl.so.4"); + curl_lib = dlopen("libcurl.so.4", RTLD_LAZY); + assert(curl_lib != NULL); + if (curl_lib == NULL) + { + UT_LOG_ERROR("dlopen failed for curl library %s: %s with major version 4\n", "libcurl.so.4", dlerror()); + return -1; + } + + // Load the curl function symbols + kvp_curl_easy_init = (curl_easy_init_t)dlsym(curl_lib, "curl_easy_init"); + assert(kvp_curl_easy_init != NULL); + kvp_curl_easy_setopt = (curl_easy_setopt_t)dlsym(curl_lib, "curl_easy_setopt"); + assert(kvp_curl_easy_setopt != NULL); + kvp_curl_easy_perform = (curl_easy_perform_t)dlsym(curl_lib, "curl_easy_perform"); + assert(kvp_curl_easy_perform != NULL); + kvp_curl_easy_getinfo = (curl_easy_getinfo_t)dlsym(curl_lib, "curl_easy_getinfo"); + assert(kvp_curl_easy_getinfo != NULL); + kvp_curl_easy_cleanup = (curl_easy_cleanup_t)dlsym(curl_lib, "curl_easy_cleanup"); + assert(kvp_curl_easy_cleanup != NULL); + kvp_curl_easy_strerror = (curl_easy_strerror_t)dlsym(curl_lib, "curl_easy_strerror"); + assert(kvp_curl_easy_strerror != NULL); + + if ((kvp_curl_easy_init == NULL) || (kvp_curl_easy_setopt == NULL) || (kvp_curl_easy_perform == NULL) || + (kvp_curl_easy_getinfo == NULL) || (kvp_curl_easy_cleanup ==NULL) || (kvp_curl_easy_strerror == NULL)) + { + UT_LOG_ERROR("dlsym failed for one or more symbols\n"); + dlclose(curl_lib); + curl_lib = NULL; + return -1; + } + + return 0; +} + ut_kvp_instance_t *ut_kvp_createInstance(void) { ut_kvp_instance_internal_t *pInstance = malloc(sizeof(ut_kvp_instance_internal_t)); @@ -136,6 +191,13 @@ ut_kvp_status_t ut_kvp_open(ut_kvp_instance_t *pInstance, char *fileName) node = process_node(fy_document_root(pInternal->fy_handle), 0); remove_include_keys(node); + if (curl_lib) + { + // Close the curl library if it was opened + dlclose(curl_lib); + curl_lib = NULL; + } + if (node == NULL) { UT_LOG_ERROR("Unable to process node"); @@ -951,17 +1013,24 @@ static struct fy_node* process_include(const char *filename, int depth, struct f if (strncmp(filename, "http:", 5) == 0 || strncmp(filename, "https:", 6) == 0) { - // URL include + // init curl symbols if not already initialized + if (curl_lib == NULL && init_curl_symbols() != 0) + { + UT_LOG_ERROR("Error: Could not initialize curl symbols\n"); + return NULL; + } + + // Initialize the memory chunk to store the downloaded data mChunk.memory = malloc(1); mChunk.size = 0; - if (!mChunk.memory) + if (mChunk.memory == NULL) { UT_LOG_ERROR( "Error: Not enough memory to store curl response\n"); return NULL; } - CURL *curl = curl_easy_init(); + CURL *curl = kvp_curl_easy_init(); if (!curl) { UT_LOG_ERROR( "Error: Could not initialize curl\n"); @@ -970,25 +1039,25 @@ static struct fy_node* process_include(const char *filename, int depth, struct f } CURLcode res; - curl_easy_setopt(curl, CURLOPT_URL, filename); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&mChunk); - res = curl_easy_perform(curl); + kvp_curl_easy_setopt(curl, CURLOPT_URL, filename); + kvp_curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback); + kvp_curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&mChunk); + res = kvp_curl_easy_perform(curl); if (res != CURLE_OK) { - UT_LOG_ERROR( "Error: curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + UT_LOG_ERROR( "Error: curl_easy_perform() failed: %s\n", kvp_curl_easy_strerror(res)); free(mChunk.memory); - curl_easy_cleanup(curl); + kvp_curl_easy_cleanup(curl); return NULL; } long response_code; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); + kvp_curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); if (response_code != 200) { UT_LOG_ERROR( "Error: HTTP request failed with code %ld\n", response_code); free(mChunk.memory); - curl_easy_cleanup(curl); + kvp_curl_easy_cleanup(curl); return NULL; } @@ -997,7 +1066,7 @@ static struct fy_node* process_include(const char *filename, int depth, struct f { UT_LOG_ERROR("Error: Cannot parse included content\n"); free(mChunk.memory); - curl_easy_cleanup(curl); + kvp_curl_easy_cleanup(curl); return NULL; } @@ -1005,7 +1074,7 @@ static struct fy_node* process_include(const char *filename, int depth, struct f // UT_LOG_DEBUG("%s memory chunk = \n%s\n", __FUNCTION__, mChunk.memory); // free(mChunk.memory); // fy_document_build_from_malloc_string(): The string is expected to have been allocated by malloc(3) and when the document is destroyed it will be automatically freed. - curl_easy_cleanup(curl); + kvp_curl_easy_cleanup(curl); return fy_document_root(doc); } else diff --git a/tests/Makefile b/tests/Makefile index bfcba10..504de34 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -75,6 +75,12 @@ build: $(ROOT_DIR)/build.sh make -C ./ut-core test @cp $(LIB_DIR)/lib* ${BIN_DIR} + @if [ -d $(LIB_DIR)/../curl ]; then \ + cp $(LIB_DIR)/../curl/lib/lib*.so* ${BIN_DIR}; \ + fi + @if [ -d $(LIB_DIR)/../openssl ]; then \ + cp $(LIB_DIR)/../openssl/lib/lib*.so* ${BIN_DIR}; \ + fi @cp ${ROOT_DIR}/src/*.sh ${BIN_DIR} @cp ${ROOT_DIR}/websocket-clients/* ${BIN_DIR} @$(ECHOE) ${GREEN}Copy Assets to [${BIN_DIR}/assets] ${NC} diff --git a/tests/src/ut_control_test.sh b/tests/src/ut_control_test.sh index e52e322..fe89ee6 100755 --- a/tests/src/ut_control_test.sh +++ b/tests/src/ut_control_test.sh @@ -25,6 +25,6 @@ MY_DIR="$(dirname $SCRIPT_EXEC)" cd "$(dirname "$0")" -export LD_LIBRARY_PATH=/usr/lib:/lib:/home/root:${MY_DIR} +export LD_LIBRARY_PATH=/usr/lib:/lib:/home/root:${MY_DIR}:${MY_DIR}/lib ./ut_control_test $@