http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/remote_service_admin_http/private/test/rsa_client_server_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http/private/test/rsa_client_server_tests.cpp b/remote_services/remote_service_admin_http/private/test/rsa_client_server_tests.cpp deleted file mode 100644 index 19cf103..0000000 --- a/remote_services/remote_service_admin_http/private/test/rsa_client_server_tests.cpp +++ /dev/null @@ -1,495 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -#include <CppUTest/TestHarness.h> -#include <remote_constants.h> -#include <constants.h> -#include "CppUTest/CommandLineTestRunner.h" -#include "../../../examples/calculator_service/public/include/calculator_service.h" - -extern "C" { - - #include <stdio.h> - #include <stdint.h> - #include <stdlib.h> - #include <string.h> - #include <ctype.h> - #include <unistd.h> - - #include "celix_launcher.h" - #include "framework.h" - #include "remote_service_admin.h" - #include "calculator_service.h" - #include "bundle.h" - - #define DISCOVERY_CFG_NAME "apache_celix_rsa_discovery_configured" - #define RSA_HTTP_NAME "apache_celix_remote_service_admin_http" - #define TOPOLOGY_MANAGER_NAME "apache_celix_rs_topology_manager" - #define CALCULATOR_PROXY "apache_celix_remoting_calculator_proxy" - #define CALCULATOR_ENDPOINT "apache_celix_remoting_calculator_endpoint" - - - static framework_pt serverFramework = NULL; - static bundle_context_pt serverContext = NULL; - - static framework_pt clientFramework = NULL; - static bundle_context_pt clientContext = NULL; - - static void setupFm(void) { - int rc = 0; - bundle_pt bundle = NULL; - - //server - rc = celixLauncher_launch("server.properties", &serverFramework); - CHECK_EQUAL(CELIX_SUCCESS, rc); - - bundle = NULL; - rc = framework_getFrameworkBundle(serverFramework, &bundle); - CHECK_EQUAL(CELIX_SUCCESS, rc); - - rc = bundle_getContext(bundle, &serverContext); - CHECK_EQUAL(CELIX_SUCCESS, rc); - - //client - rc = celixLauncher_launch("client.properties", &clientFramework); - CHECK_EQUAL(CELIX_SUCCESS, rc); - - bundle = NULL; - rc = framework_getFrameworkBundle(clientFramework, &bundle); - CHECK_EQUAL(CELIX_SUCCESS, rc); - - rc = bundle_getContext(bundle, &clientContext); - CHECK_EQUAL(CELIX_SUCCESS, rc); - } - - static void teardownFm(void) { - celixLauncher_stop(serverFramework); - celixLauncher_waitForShutdown(serverFramework); - celixLauncher_destroy(serverFramework); - - celixLauncher_stop(clientFramework); - celixLauncher_waitForShutdown(clientFramework); - celixLauncher_destroy(clientFramework); - - serverContext = NULL; - serverFramework = NULL; - clientContext = NULL; - clientFramework = NULL; - } - - static void test1(void) { - celix_status_t status; - service_reference_pt ref = NULL; - calculator_service_pt calcService = NULL; - int retries = 4; - - while (ref == NULL && retries > 0) { - printf("Waiting for service .. %d\n", retries); - status = bundleContext_getServiceReference(clientContext, (char *) CALCULATOR_SERVICE, &ref); - usleep(1000000); - --retries; - } - - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK(ref != NULL); - - status = bundleContext_getService(clientContext, ref, (void **) &calcService); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK(calcService != NULL); - - double result = 0; - status = calcService->add(calcService->calculator, 2.0, 5.0, &result); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK_EQUAL(7.0, result); - - bundleContext_ungetService(clientContext, ref, NULL); - bundleContext_ungetServiceReference(clientContext, ref); - } - - - static celix_status_t getPermutations(array_list_pt bundleIds, int from, int to, array_list_pt permutations) { - celix_status_t status = CELIX_SUCCESS; - int i = 0; - - if (from == to) { - long* permutation = (long*) calloc(to + 1, sizeof(*permutation)); - - if (!permutation) { - status = CELIX_ENOMEM; - } else { - for (; i <= to; i++) { - permutation[i] = (long) arrayList_get(bundleIds, i); - } - - arrayList_add(permutations, permutation); - } - } else { - for (i = from; i <= to; i++) { - long fromOrg = (long) arrayList_get(bundleIds, from); - long iOrg = (long) arrayList_get(bundleIds, i); - - arrayList_set(bundleIds, from, (void*) iOrg); - arrayList_set(bundleIds, i, (void*) fromOrg); - - status = getPermutations(bundleIds, from + 1, to, permutations); - - arrayList_set(bundleIds, from, (void*) fromOrg); - arrayList_set(bundleIds, i, (void*) iOrg); - } - } - - return status; - } - - static celix_status_t getSpecifiedBundles(bundle_context_pt context, array_list_pt bundleNames, array_list_pt retrievedBundles) { - celix_status_t status; - array_list_pt bundles = NULL; - - status = bundleContext_getBundles(context, &bundles); - - if (status == CELIX_SUCCESS) { - unsigned int size = arrayList_size(bundles); - unsigned int i; - - for (i = 0; i < size; i++) { - module_pt module = NULL; - const char *name = NULL; - - bundle_pt bundle = (bundle_pt) arrayList_get(bundles, i); - - status = bundle_getCurrentModule(bundle, &module); - - if (status == CELIX_SUCCESS) { - status = module_getSymbolicName(module, &name); - } - - if (status == CELIX_SUCCESS) { - - printf("FOUND %s\n", name); - - array_list_iterator_pt iter = arrayListIterator_create(bundleNames); - - while(arrayListIterator_hasNext(iter)) { - char* bundleName = (char*) arrayListIterator_next(iter); - - if ((strcmp(name, bundleName) == 0)) { - - bundle_archive_pt bundleArchive = NULL; - long bundleId = -1; - - status = bundle_getArchive(bundle, &bundleArchive); - - if (status == CELIX_SUCCESS) { - status = bundleArchive_getId(bundleArchive, &bundleId); - } - - if (status == CELIX_SUCCESS) { - arrayList_add(retrievedBundles, (void*) bundleId); - break; - } - } - } - - arrayListIterator_destroy(iter); - - } - } - - arrayList_destroy(bundles); - } - - return status; - } - - static celix_status_t stopStartPermutation(bundle_context_pt context, long* permutation, int size) { - celix_status_t status = CELIX_SUCCESS; - int y = 0; - - printf("Test stop/start permutation: "); - - for (y = 0; (y < size) && (status == CELIX_SUCCESS); y++) { - bundle_pt bundle = NULL; - - status = bundleContext_getBundleById(context, permutation[y], &bundle); - - if (status == CELIX_SUCCESS) { - module_pt module = NULL; - const char *name = NULL; - - status = bundle_getCurrentModule(bundle, &module); - - if (status == CELIX_SUCCESS) { - status = module_getSymbolicName(module, &name); - printf("%s (%ld) ", name, permutation[y]); - } - } - } - printf("\n"); - - // stop all bundles - if (status == CELIX_SUCCESS) { - for (y = 0; (y < size) && (status == CELIX_SUCCESS); y++) { - bundle_pt bundle = NULL; - - status = bundleContext_getBundleById(context, permutation[y], &bundle); - - if (status == CELIX_SUCCESS) { - printf("stop bundle: %ld\n", permutation[y]); - status = bundle_stop(bundle); - } - } - } - - // verify stop state - if (status == CELIX_SUCCESS) { - for (y = 0; (y < size) && (status == CELIX_SUCCESS); y++) { - bundle_pt bundle = NULL; - - status = bundleContext_getBundleById(context, permutation[y], &bundle); - - if (status == CELIX_SUCCESS) { - bundle_state_e state; - status = bundle_getState(bundle, &state); - - if (state != OSGI_FRAMEWORK_BUNDLE_RESOLVED) { - printf("bundle %ld has state %d (should be %d) \n", permutation[y], state, OSGI_FRAMEWORK_BUNDLE_RESOLVED); - status = CELIX_ILLEGAL_STATE; - } - } - } - } - - // start all bundles - if (status == CELIX_SUCCESS) { - - for (y = 0; (y < size) && (status == CELIX_SUCCESS); y++) { - bundle_pt bundle = NULL; - - status = bundleContext_getBundleById(context, permutation[y], &bundle); - - if (status == CELIX_SUCCESS) { - printf("start bundle: %ld\n", permutation[y]); - status = bundle_start(bundle); - } - } - } - - // verify started state - if (status == CELIX_SUCCESS) { - for (y = 0; (y < size) && (status == CELIX_SUCCESS); y++) { - bundle_pt bundle = NULL; - - status = bundleContext_getBundleById(context, permutation[y], &bundle); - - if (status == CELIX_SUCCESS) { - bundle_state_e state; - status = bundle_getState(bundle, &state); - - if (state != OSGI_FRAMEWORK_BUNDLE_ACTIVE) { - printf("bundle %ld has state %d (should be %d) \n", permutation[y], state, OSGI_FRAMEWORK_BUNDLE_ACTIVE); - status = CELIX_ILLEGAL_STATE; - } - } - } - } - - return status; - } - - static void testImport(void) { - celix_status_t status; - array_list_pt bundleNames = NULL; - array_list_pt bundlePermutations = NULL; - array_list_pt rsaBundles = NULL; - unsigned int i, size; - - arrayList_create(&bundleNames); - arrayList_create(&bundlePermutations); - arrayList_create(&rsaBundles); - - arrayList_add(bundleNames, (void*) DISCOVERY_CFG_NAME); - arrayList_add(bundleNames, (void*) RSA_HTTP_NAME); - arrayList_add(bundleNames, (void*) TOPOLOGY_MANAGER_NAME); - - status = getSpecifiedBundles(clientContext, bundleNames, rsaBundles); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK_EQUAL(arrayList_size(rsaBundles), arrayList_size(bundleNames)); - - status = getPermutations(rsaBundles, 0, arrayList_size(rsaBundles) - 1, bundlePermutations); - CHECK_EQUAL(CELIX_SUCCESS, status); - - size = arrayList_size(bundlePermutations); - - for (i = 0; i < size; ++i) { - long* singlePermutation = (long*) arrayList_get(bundlePermutations, i); - - status = stopStartPermutation(clientContext, singlePermutation, arrayList_size(rsaBundles)); - CHECK_EQUAL(CELIX_SUCCESS, status); - - // check whether calc service is available - test1(); - - free(singlePermutation); - } - - arrayList_destroy(bundlePermutations); - arrayList_destroy(bundleNames); - arrayList_destroy(rsaBundles); - } - - static void testExport(void) { - celix_status_t status; - array_list_pt bundleNames = NULL; - array_list_pt bundlePermutations = NULL; - array_list_pt rsaBundles = NULL; - - unsigned int i, size; - - arrayList_create(&bundleNames); - arrayList_create(&bundlePermutations); - arrayList_create(&rsaBundles); - - arrayList_add(bundleNames, (void*) DISCOVERY_CFG_NAME); - arrayList_add(bundleNames, (void*) RSA_HTTP_NAME); - arrayList_add(bundleNames, (void*) TOPOLOGY_MANAGER_NAME); - - status = getSpecifiedBundles(serverContext, bundleNames, rsaBundles); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK_EQUAL(arrayList_size(rsaBundles), arrayList_size(bundleNames)); - - status = getPermutations(rsaBundles, 0, arrayList_size(rsaBundles) - 1, bundlePermutations); - CHECK_EQUAL(CELIX_SUCCESS, status); - - size = arrayList_size(bundlePermutations); - - for (i = 0; i < size; ++i) { - long* singlePermutation = (long*) arrayList_get(bundlePermutations, i); - - status = stopStartPermutation(serverContext, singlePermutation, arrayList_size(rsaBundles)); - CHECK_EQUAL(CELIX_SUCCESS, status); - - /* we need to sleep here for a bit to ensure - * that the client has flushed the old discovery - * values - */ - sleep(2); - - // check whether calc service is available - test1(); - - free(singlePermutation); - } - - arrayList_destroy(bundlePermutations); - arrayList_destroy(bundleNames); - arrayList_destroy(rsaBundles); - } - - static void testProxyRemoval(void) { - celix_status_t status; - bundle_pt bundle = NULL; - array_list_pt bundleNames = NULL; - array_list_pt proxyBundle = NULL; - service_reference_pt ref = NULL; - - arrayList_create(&bundleNames); - arrayList_create(&proxyBundle); - - arrayList_add(bundleNames, (void*) CALCULATOR_PROXY); - status = getSpecifiedBundles(clientContext, bundleNames, proxyBundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK_EQUAL(arrayList_size(proxyBundle), arrayList_size(bundleNames)); - - status = bundleContext_getBundleById(clientContext, (long) arrayList_get(proxyBundle, 0), &bundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - - status = bundle_stop(bundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - - status = bundleContext_getServiceReference(clientContext, (char *) CALCULATOR_SERVICE, &ref); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK(ref == NULL); - - arrayList_destroy(bundleNames); - arrayList_destroy(proxyBundle); - } - - /* - static void testEndpointRemoval(void) { - celix_status_t status; - bundle_pt bundle = NULL; - array_list_pt bundleNames = NULL; - array_list_pt endpointBundle = NULL; - service_reference_pt ref = NULL; - - arrayList_create(&bundleNames); - arrayList_create(&endpointBundle); - - arrayList_add(bundleNames, (void*) CALCULATOR_ENDPOINT); - status = getSpecifiedBundles(serverContext, bundleNames, endpointBundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK_EQUAL(arrayList_size(endpointBundle), arrayList_size(bundleNames)); - - status = bundleContext_getBundleById(serverContext, (long) arrayList_get(endpointBundle, 0), &bundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - - status = bundle_stop(bundle); - CHECK_EQUAL(CELIX_SUCCESS, status); - - status = bundleContext_getServiceReference(serverContext, (char *) CALCULATOR_SERVICE, &ref); - CHECK_EQUAL(CELIX_SUCCESS, status); - CHECK(ref == NULL); - - arrayList_destroy(bundleNames); - arrayList_destroy(endpointBundle); - } - */ -} - -TEST_GROUP(RsaHttpClientServerTests) { - void setup() { - setupFm(); - } - - void teardown() { - teardownFm(); - } -}; - -TEST(RsaHttpClientServerTests, Test1) { - test1(); -} - -TEST(RsaHttpClientServerTests, TestImport) { - testImport(); -} - -TEST(RsaHttpClientServerTests, TestExport) { - testExport(); -} - -TEST(RsaHttpClientServerTests, TestProxyRemoval) { - testProxyRemoval(); -} -/* -TEST(RsaHttpClientServerTests, TestEndpointRemoval) { - // test is currenlty failing - testEndpointRemoval(); -} -*/ -
http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/remote_service_admin_http/private/test/run_tests.cpp ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http/private/test/run_tests.cpp b/remote_services/remote_service_admin_http/private/test/run_tests.cpp deleted file mode 100644 index fb6ca3a..0000000 --- a/remote_services/remote_service_admin_http/private/test/run_tests.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -#include <CppUTest/TestHarness.h> -#include "CppUTest/CommandLineTestRunner.h" - -int main(int argc, char** argv) { - return RUN_ALL_TESTS(argc, argv); -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/remote_service_admin_http/private/test/server.properties.in ---------------------------------------------------------------------- diff --git a/remote_services/remote_service_admin_http/private/test/server.properties.in b/remote_services/remote_service_admin_http/private/test/server.properties.in deleted file mode 100644 index e7d48ab..0000000 --- a/remote_services/remote_service_admin_http/private/test/server.properties.in +++ /dev/null @@ -1,25 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -cosgi.auto.start.1=@rsa_bundle_file@ @calc_bundle_file@ @discovery_configured_bundle_file@ @topology_manager_bundle_file@ -LOGHELPER_ENABLE_STDOUT_FALLBACK=true -ENDPOINTS=@server_endpoints@ -RSA_PORT=50882 -DISCOVERY_CFG_SERVER_PORT=50992 -org.osgi.framework.storage.clean=onFirstInit -org.osgi.framework.storage=.cacheServer -DISCOVERY_CFG_POLL_INTERVAL=1 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/topology_manager/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/CMakeLists.txt b/remote_services/topology_manager/CMakeLists.txt index 46a3bac..4bac4fd 100644 --- a/remote_services/topology_manager/CMakeLists.txt +++ b/remote_services/topology_manager/CMakeLists.txt @@ -29,8 +29,6 @@ if (RSA_TOPOLOGY_MANAGER) private/src/scope private/src/activator - ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c - private/include/topology_manager.h public/include/tm_scope.h VERSION 0.9.0 @@ -38,6 +36,7 @@ if (RSA_TOPOLOGY_MANAGER) NAME "Apache Celix RS Topology Manager" ) + target_link_libraries(topology_manager PRIVATE Celix::log_helper) install_bundle(topology_manager) @@ -50,6 +49,4 @@ if (RSA_TOPOLOGY_MANAGER) include_directories(${CPPUTEST_EXT_INCLUDE_DIR}) add_subdirectory(tms_tst) endif (ENABLE_TESTING) - - target_link_libraries(topology_manager celix_framework celix_utils) endif (RSA_TOPOLOGY_MANAGER) http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/topology_manager/tms_tst/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/tms_tst/CMakeLists.txt b/remote_services/topology_manager/tms_tst/CMakeLists.txt index 16ad011..dc671e4 100644 --- a/remote_services/topology_manager/tms_tst/CMakeLists.txt +++ b/remote_services/topology_manager/tms_tst/CMakeLists.txt @@ -39,7 +39,7 @@ add_executable(test_tm_scoped ${PROJECT_SOURCE_DIR}/remote_services/remote_service_admin/private/src/endpoint_description.c ) -target_link_libraries(test_tm_scoped celix_framework celix_utils ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY}) +target_link_libraries(test_tm_scoped Celix::framework ${CPPUTEST_LIBRARY} ${JANSSON_LIBRARY} Celix::log_helper) add_dependencies(test_tm_scoped remote_service_admin_dfi topology_manager calculator) http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt index 6e269f5..9e36e4c 100644 --- a/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt +++ b/remote_services/topology_manager/tms_tst/bundle/CMakeLists.txt @@ -32,4 +32,4 @@ bundle_files(topology_manager_test_bundle DESTINATION . ) -target_link_libraries(topology_manager_test_bundle ${CPPUTEST_LIBRARY} celix_framework celix_utils) +target_link_libraries(topology_manager_test_bundle PRIVATE ${CPPUTEST_LIBRARY}) http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt index a19efc7..b961de7 100644 --- a/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt +++ b/remote_services/topology_manager/tms_tst/disc_mock/CMakeLists.txt @@ -30,4 +30,4 @@ add_bundle(topology_manager_disc_mock_bundle disc_mock_service.c ) -target_link_libraries(topology_manager_disc_mock_bundle ${CPPUTEST_LIBRARY} celix_framework celix_utils) +target_link_libraries(topology_manager_disc_mock_bundle PRIVATE ${CPPUTEST_LIBRARY} Celix::framework) http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/remote_shell/CMakeLists.txt b/remote_shell/CMakeLists.txt index 7c37d13..a7f5d36 100644 --- a/remote_shell/CMakeLists.txt +++ b/remote_shell/CMakeLists.txt @@ -22,25 +22,23 @@ if (REMOTE_SHELL) VERSION "0.0.2" NAME: "Apache Celix Remote Shell" SOURCES - private/src/activator - private/src/connection_listener - private/src/shell_mediator - private/src/remote_shell - - ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c - - private/include/remote_shell.h - private/include/connection_listener.h + src/activator + src/connection_listener + src/shell_mediator + src/remote_shell ) - + + target_include_directories(remote_shell PRIVATE src) + target_link_libraries(remote_shell PRIVATE log_helper) install_bundle(remote_shell) - - include_directories("private/include") + include_directories("${PROJECT_SOURCE_DIR}/utils/public/include") - include_directories("${PROJECT_SOURCE_DIR}/shell/public/include") include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include") - target_link_libraries(remote_shell celix_framework) + target_link_libraries(remote_shell PRIVATE Celix::shell_api) + + #Alias setup to match external usage + add_library(Celix::remote_shell ALIAS remote_shell) - add_deploy("remote_shell_deploy" NAME "remote_shell" BUNDLES shell remote_shell shell_tui log_service) + add_deploy("remote_shell_deploy" NAME "remote_shell" BUNDLES Celix::shell Celix::remote_shell Celix::shell_tui log_service) endif (REMOTE_SHELL) http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/include/connection_listener.h ---------------------------------------------------------------------- diff --git a/remote_shell/private/include/connection_listener.h b/remote_shell/private/include/connection_listener.h deleted file mode 100644 index 392d6ec..0000000 --- a/remote_shell/private/include/connection_listener.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * connection_listener.h - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#ifndef connectionListener_H_ -#define connectionListener_H_ - -#include <bundle_context.h> -#include <celix_errno.h> - -#include "remote_shell.h" - -typedef struct connection_listener *connection_listener_pt; - -celix_status_t connectionListener_create(remote_shell_pt remoteShell, int port, connection_listener_pt *instance); -celix_status_t connectionListener_destroy(connection_listener_pt instance); -celix_status_t connectionListener_start(connection_listener_pt instance); -celix_status_t connectionListener_stop(connection_listener_pt instance); - -#endif /* connectionListener_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/include/remote_shell.h ---------------------------------------------------------------------- diff --git a/remote_shell/private/include/remote_shell.h b/remote_shell/private/include/remote_shell.h deleted file mode 100644 index 55249a8..0000000 --- a/remote_shell/private/include/remote_shell.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * remote_shell.h - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#ifndef REMOTE_SHELL_H_ -#define REMOTE_SHELL_H_ - -#include <bundle_context.h> -#include <celix_errno.h> - -#include "shell_mediator.h" - -struct remote_shell { - log_helper_pt* loghelper; - shell_mediator_pt mediator; - celix_thread_mutex_t mutex; - int maximumConnections; - - array_list_pt connections; -}; -typedef struct remote_shell *remote_shell_pt; - -celix_status_t remoteShell_create(shell_mediator_pt mediator, int maximumConnections, remote_shell_pt *instance); -celix_status_t remoteShell_destroy(remote_shell_pt instance); -celix_status_t remoteShell_addConnection(remote_shell_pt instance, int socket); -celix_status_t remoteShell_stopConnections(remote_shell_pt instance); - -#endif /* REMOTE_SHELL_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/include/shell_mediator.h ---------------------------------------------------------------------- diff --git a/remote_shell/private/include/shell_mediator.h b/remote_shell/private/include/shell_mediator.h deleted file mode 100644 index 24e8250..0000000 --- a/remote_shell/private/include/shell_mediator.h +++ /dev/null @@ -1,54 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * shell_mediator.h - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - - -#ifndef shellMediator_H_ -#define shellMediator_H_ - -#include <bundle_context.h> -#include <service_tracker.h> -#include <celix_errno.h> - -#include <shell.h> - -struct shell_mediator { - - log_helper_pt loghelper; - bundle_context_pt context; - service_tracker_pt tracker; - celix_thread_mutex_t mutex; - - //protected by mutex - shell_service_pt shellService; -}; -typedef struct shell_mediator *shell_mediator_pt; - -celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance); -celix_status_t shellMediator_stop(shell_mediator_pt instance); -celix_status_t shellMediator_destroy(shell_mediator_pt instance); -celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err); - -#endif /* shellMediator_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/src/activator.c ---------------------------------------------------------------------- diff --git a/remote_shell/private/src/activator.c b/remote_shell/private/src/activator.c deleted file mode 100644 index 541eda6..0000000 --- a/remote_shell/private/src/activator.c +++ /dev/null @@ -1,153 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * activator.c - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <celix_errno.h> - -#include <stdlib.h> - -#include "bundle_activator.h" -#include "bundle_context.h" - -#include "log_helper.h" -#include "connection_listener.h" -#include "shell_mediator.h" -#include "remote_shell.h" - -#define REMOTE_SHELL_TELNET_PORT_PROPERTY_NAME "remote.shell.telnet.port" -#define DEFAULT_REMOTE_SHELL_TELNET_PORT 6666 - -#define REMOTE_SHELL_TELNET_MAXCONN_PROPERTY_NAME "remote.shell.telnet.maxconn" -#define DEFAULT_REMOTE_SHELL_TELNET_MAXCONN 2 - -struct bundle_instance { - log_helper_pt loghelper; - shell_mediator_pt shellMediator; - remote_shell_pt remoteShell; - connection_listener_pt connectionListener; -}; - -typedef struct bundle_instance *bundle_instance_pt; - -static int bundleActivator_getPort(bundle_instance_pt bi, bundle_context_pt context); -static int bundleActivator_getMaximumConnections(bundle_instance_pt bi, bundle_context_pt context); -static int bundleActivator_getProperty(bundle_instance_pt bi, bundle_context_pt context, char * propertyName, int defaultValue); - -celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { - celix_status_t status = CELIX_SUCCESS; - - bundle_instance_pt bi = (bundle_instance_pt) calloc(1, sizeof(struct bundle_instance)); - - if (!bi) - { - status = CELIX_ENOMEM; - } - else if (userData != NULL) { - bi->shellMediator = NULL; - bi->remoteShell = NULL; - bi->connectionListener = NULL; - - status = logHelper_create(context, &bi->loghelper); - - (*userData) = bi; - } else { - status = CELIX_ILLEGAL_ARGUMENT; - free(bi); - } - - return status; -} - -celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; - bundle_instance_pt bi = (bundle_instance_pt) userData; - - int port = bundleActivator_getPort(bi, context); - int maxConn = bundleActivator_getMaximumConnections(bi, context); - - status = logHelper_start(bi->loghelper); - - status = CELIX_DO_IF(status, shellMediator_create(context, &bi->shellMediator)); - status = CELIX_DO_IF(status, remoteShell_create(bi->shellMediator, maxConn, &bi->remoteShell)); - status = CELIX_DO_IF(status, connectionListener_create(bi->remoteShell, port, &bi->connectionListener)); - status = CELIX_DO_IF(status, connectionListener_start(bi->connectionListener)); - - return status; -} - -celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; - bundle_instance_pt bi = (bundle_instance_pt) userData; - - connectionListener_stop(bi->connectionListener); - shellMediator_stop(bi->shellMediator); - shellMediator_destroy(bi->shellMediator); - - remoteShell_stopConnections(bi->remoteShell); - - status = logHelper_stop(bi->loghelper); - - return status; -} - -celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { - celix_status_t status = CELIX_SUCCESS; - bundle_instance_pt bi = (bundle_instance_pt) userData; - - connectionListener_destroy(bi->connectionListener); - status = logHelper_destroy(&bi->loghelper); - - return status; -} - -static int bundleActivator_getPort(bundle_instance_pt bi, bundle_context_pt context) { - return bundleActivator_getProperty(bi, context, REMOTE_SHELL_TELNET_PORT_PROPERTY_NAME, DEFAULT_REMOTE_SHELL_TELNET_PORT); -} - -static int bundleActivator_getMaximumConnections(bundle_instance_pt bi, bundle_context_pt context) { - return bundleActivator_getProperty(bi, context, REMOTE_SHELL_TELNET_MAXCONN_PROPERTY_NAME, DEFAULT_REMOTE_SHELL_TELNET_MAXCONN); -} - -static int bundleActivator_getProperty(bundle_instance_pt bi, bundle_context_pt context, char* propertyName, int defaultValue) { - const char *strValue = NULL; - int value; - - bundleContext_getProperty(context, propertyName, &strValue); - if (strValue != NULL) { - char* endptr = (char*)strValue; - - errno = 0; - value = strtol(strValue, &endptr, 10); - if (*endptr || errno != 0) { - logHelper_log(bi->loghelper, OSGI_LOGSERVICE_WARNING, "incorrect format for %s", propertyName); - value = defaultValue; - } - } - else { - value = defaultValue; - } - - return value; -} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/src/connection_listener.c ---------------------------------------------------------------------- diff --git a/remote_shell/private/src/connection_listener.c b/remote_shell/private/src/connection_listener.c deleted file mode 100644 index 3bef9e5..0000000 --- a/remote_shell/private/src/connection_listener.c +++ /dev/null @@ -1,221 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * connection_listener.c - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdlib.h> -#include <string.h> -#include <celix_errno.h> -#include <stdio.h> -#include <errno.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <netdb.h> -#include <fcntl.h> - -#include "log_service.h" -#include "log_helper.h" - -#include "connection_listener.h" - -#include "shell_mediator.h" -#include "remote_shell.h" - -#define CONNECTION_LISTENER_TIMEOUT_SEC 5 - -struct connection_listener { - //constant - int port; - log_helper_pt* loghelper; - remote_shell_pt remoteShell; - celix_thread_mutex_t mutex; - - //protected by mutex - bool running; - celix_thread_t thread; - fd_set pollset; -}; - -static void* connection_listener_thread(void *data); - -celix_status_t connectionListener_create(remote_shell_pt remoteShell, int port, connection_listener_pt *instance) { - celix_status_t status = CELIX_SUCCESS; - (*instance) = calloc(1, sizeof(**instance)); - - if ((*instance) != NULL) { - (*instance)->port = port; - (*instance)->remoteShell = remoteShell; - (*instance)->running = false; - (*instance)->loghelper = remoteShell->loghelper; - - FD_ZERO(&(*instance)-> pollset); - - status = celixThreadMutex_create(&(*instance)->mutex, NULL); - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t connectionListener_start(connection_listener_pt instance) { - celix_status_t status = CELIX_SUCCESS; - celixThreadMutex_lock(&instance->mutex); - celixThread_create(&instance->thread, NULL, connection_listener_thread, instance); - celixThreadMutex_unlock(&instance->mutex); - return status; -} - -celix_status_t connectionListener_stop(connection_listener_pt instance) { - celix_status_t status = CELIX_SUCCESS; - celix_thread_t thread; - fd_set pollset; - - instance->running = false; - FD_ZERO(&pollset); - - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "CONNECTION_LISTENER: Stopping thread\n"); - - celixThreadMutex_lock(&instance->mutex); - thread = instance->thread; - - pollset = instance->pollset; - celixThreadMutex_unlock(&instance->mutex); - - celixThread_join(thread, NULL); - return status; -} - -celix_status_t connectionListener_destroy(connection_listener_pt instance) { - free(instance); - - return CELIX_SUCCESS; -} - -static void* connection_listener_thread(void *data) { - celix_status_t status = CELIX_BUNDLE_EXCEPTION; - connection_listener_pt instance = data; - struct timeval timeout; /* Timeout for select */ - fd_set active_fd_set; - FD_ZERO(&active_fd_set); - int listenSocket = 0; - int on = 1; - - struct addrinfo *result, *rp; - struct addrinfo hints; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ - hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ - hints.ai_protocol = 0; /* Any protocol */ - hints.ai_canonname = NULL; - hints.ai_addr = NULL; - hints.ai_next = NULL; - - char portStr[10]; - snprintf(&portStr[0], 10, "%d", instance->port); - - getaddrinfo(NULL, portStr, &hints, &result); - - for (rp = result; rp != NULL && status == CELIX_BUNDLE_EXCEPTION; rp = rp->ai_next) { - - status = CELIX_BUNDLE_EXCEPTION; - - /* Create socket */ - listenSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); - if (listenSocket < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "Error creating socket: %s", strerror(errno)); - } - else if (setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "cannot set socket option: %s", strerror(errno)); - } - else if (bind(listenSocket, rp->ai_addr, rp->ai_addrlen) < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "cannot bind: %s", strerror(errno)); - } - else if (listen(listenSocket, 5) < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "listen failed: %s", strerror(errno)); - } - else { - status = CELIX_SUCCESS; - } - } - - if (status == CELIX_SUCCESS) { - - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "Remote Shell accepting connections on port %d", instance->port); - - celixThreadMutex_lock(&instance->mutex); - instance->pollset = active_fd_set; - celixThreadMutex_unlock(&instance->mutex); - - instance->running = true; - - while (status == CELIX_SUCCESS && instance->running) { - int selectRet = -1; - do { - timeout.tv_sec = CONNECTION_LISTENER_TIMEOUT_SEC; - timeout.tv_usec = 0; - - FD_ZERO(&active_fd_set); - FD_SET(listenSocket, &active_fd_set); - - selectRet = select(listenSocket + 1, &active_fd_set, NULL, NULL, &timeout); - } while (selectRet == -1 && errno == EINTR && instance->running == true); - if (selectRet < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "select on listenSocket failed: %s", strerror(errno)); - status = CELIX_BUNDLE_EXCEPTION; - } - else if (selectRet == 0) { - /* do nothing here */ - } - else if (FD_ISSET(listenSocket, &active_fd_set)) { - int acceptedSocket = accept(listenSocket, NULL, NULL); - - if (acceptedSocket < 0) { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "REMOTE_SHELL: accept failed: %s.", strerror(errno)); - status = CELIX_BUNDLE_EXCEPTION; - } - else { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "REMOTE_SHELL: connection established."); - remoteShell_addConnection(instance->remoteShell, acceptedSocket); - } - } - else { - logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_DEBUG, "REMOTE_SHELL: received data on a not-expected file-descriptor?"); - } - } - } - - if (listenSocket >= 0) { - close(listenSocket); - } - - freeaddrinfo(result); - - return NULL; -} - http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/src/remote_shell.c ---------------------------------------------------------------------- diff --git a/remote_shell/private/src/remote_shell.c b/remote_shell/private/src/remote_shell.c deleted file mode 100644 index 8f42778..0000000 --- a/remote_shell/private/src/remote_shell.c +++ /dev/null @@ -1,242 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * remote_shell.c - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <utils.h> -#include <array_list.h> -#include <sys/socket.h> - -#include "log_helper.h" - -#include "log_service.h" -#include "remote_shell.h" - -#define COMMAND_BUFF_SIZE (256) - -#define RS_PROMPT ("-> ") -#define RS_WELCOME ("\n---- Apache Celix Remote Shell ----\n---- Type exit to disconnect ----\n\n-> ") -#define RS_GOODBYE ("Goobye!\n") -#define RS_ERROR ("Error executing command!\n") -#define RS_MAXIMUM_CONNECTIONS_REACHED ("Maximum number of connections reached. Disconnecting ...\n") - -#define CONNECTION_LISTENER_TIMEOUT_SEC 5 - - - -struct connection { - remote_shell_pt parent; - FILE *socketStream; - fd_set pollset; - bool threadRunning; -}; - -typedef struct connection *connection_pt; - -static celix_status_t remoteShell_connection_print(connection_pt connection, char * text); -static celix_status_t remoteShell_connection_execute(connection_pt connection, char *command); -static void* remoteShell_connection_run(void *data); - -celix_status_t remoteShell_create(shell_mediator_pt mediator, int maximumConnections, remote_shell_pt *instance) { - celix_status_t status = CELIX_SUCCESS; - (*instance) = calloc(1, sizeof(**instance)); - if ((*instance) != NULL) { - (*instance)->mediator = mediator; - (*instance)->maximumConnections = maximumConnections; - (*instance)->connections = NULL; - (*instance)->loghelper = &mediator->loghelper; - - status = celixThreadMutex_create(&(*instance)->mutex, NULL); - - if (status == CELIX_SUCCESS) { - status = arrayList_create(&(*instance)->connections); - } - } else { - status = CELIX_ENOMEM; - } - return status; -} - -celix_status_t remoteShell_destroy(remote_shell_pt instance) { - celix_status_t status = CELIX_SUCCESS; - - remoteShell_stopConnections(instance); - - celixThreadMutex_lock(&instance->mutex); - arrayList_destroy(instance->connections); - celixThreadMutex_unlock(&instance->mutex); - - return status; -} - -celix_status_t remoteShell_addConnection(remote_shell_pt instance, int socket) { - celix_status_t status = CELIX_SUCCESS; - connection_pt connection = calloc(1, sizeof(struct connection)); - - if (connection != NULL) { - connection->parent = instance; - connection->threadRunning = false; - connection->socketStream = fdopen(socket, "w"); - - if (connection->socketStream != NULL) { - - celixThreadMutex_lock(&instance->mutex); - - if (arrayList_size(instance->connections) < instance->maximumConnections) { - celix_thread_t connectionRunThread = celix_thread_default; - arrayList_add(instance->connections, connection); - status = celixThread_create(&connectionRunThread, NULL, &remoteShell_connection_run, connection); - } else { - status = CELIX_BUNDLE_EXCEPTION; - remoteShell_connection_print(connection, RS_MAXIMUM_CONNECTIONS_REACHED); - } - celixThreadMutex_unlock(&instance->mutex); - - } else { - status = CELIX_BUNDLE_EXCEPTION; - } - } else { - status = CELIX_ENOMEM; - } - - if (status != CELIX_SUCCESS && connection != NULL) { - if (connection->socketStream != NULL) { - fclose(connection->socketStream); - } - free(connection); - } - - return status; -} - -celix_status_t remoteShell_stopConnections(remote_shell_pt instance) { - celix_status_t status = CELIX_SUCCESS; - int length = 0; - int i = 0; - - celixThreadMutex_lock(&instance->mutex); - length = arrayList_size(instance->connections); - - for (i = 0; i < length; i += 1) { - connection_pt connection = arrayList_get(instance->connections, i); - connection->threadRunning = false; - } - - celixThreadMutex_unlock(&instance->mutex); - - return status; -} - -void *remoteShell_connection_run(void *data) { - celix_status_t status = CELIX_SUCCESS; - connection_pt connection = data; - size_t len; - int result; - struct timeval timeout; /* Timeout for select */ - - int fd = fileno(connection->socketStream); - - connection->threadRunning = true; - status = remoteShell_connection_print(connection, RS_WELCOME); - - while (status == CELIX_SUCCESS && connection->threadRunning == true) { - do { - timeout.tv_sec = CONNECTION_LISTENER_TIMEOUT_SEC; - timeout.tv_usec = 0; - - FD_ZERO(&connection->pollset); - FD_SET(fd, &connection->pollset); - result = select(fd + 1, &connection->pollset, NULL, NULL, &timeout); - } while (result == -1 && errno == EINTR && connection->threadRunning == true); - - /* The socket_fd has data available to be read */ - if (result > 0 && FD_ISSET(fd, &connection->pollset)) { - char buff[COMMAND_BUFF_SIZE]; - - len = recv(fd, buff, COMMAND_BUFF_SIZE - 1, 0); - if (len < COMMAND_BUFF_SIZE) { - celix_status_t commandStatus = CELIX_SUCCESS; - buff[len] = '\0'; - - commandStatus = remoteShell_connection_execute(connection, buff); - - if (commandStatus == CELIX_SUCCESS) { - remoteShell_connection_print(connection, RS_PROMPT); - } else if (commandStatus == CELIX_FILE_IO_EXCEPTION) { - //exit command - break; - } else { //error - remoteShell_connection_print(connection, RS_ERROR); - remoteShell_connection_print(connection, RS_PROMPT); - } - - } else { - logHelper_log(*connection->parent->loghelper, OSGI_LOGSERVICE_ERROR, "REMOTE_SHELL: Error while retrieving data"); - } - } - } - - remoteShell_connection_print(connection, RS_GOODBYE); - - logHelper_log(*connection->parent->loghelper, OSGI_LOGSERVICE_INFO, "REMOTE_SHELL: Closing socket"); - celixThreadMutex_lock(&connection->parent->mutex); - arrayList_removeElement(connection->parent->connections, connection); - celixThreadMutex_unlock(&connection->parent->mutex); - - fclose(connection->socketStream); - - return NULL; -} - -static celix_status_t remoteShell_connection_execute(connection_pt connection, char *command) { - celix_status_t status = CELIX_SUCCESS; - - if (status == CELIX_SUCCESS) { - char *dline = strdup(command); - char *line = utils_stringTrim(dline); - int len = strlen(line); - - if (len == 0) { - //ignore - } else if (len == 4 && strncmp("exit", line, 4) == 0) { - status = CELIX_FILE_IO_EXCEPTION; - } else { - status = shellMediator_executeCommand(connection->parent->mediator, line, connection->socketStream, connection->socketStream); - fflush(connection->socketStream); - } - - free(dline); - } - - return status; -} - -celix_status_t remoteShell_connection_print(connection_pt connection, char *text) { - size_t len = strlen(text); - int fd = fileno(connection->socketStream); - return (send(fd, text, len, 0) > 0) ? CELIX_SUCCESS : CELIX_FILE_IO_EXCEPTION; -} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/private/src/shell_mediator.c ---------------------------------------------------------------------- diff --git a/remote_shell/private/src/shell_mediator.c b/remote_shell/private/src/shell_mediator.c deleted file mode 100644 index d9722a9..0000000 --- a/remote_shell/private/src/shell_mediator.c +++ /dev/null @@ -1,139 +0,0 @@ -/** - *Licensed to the Apache Software Foundation (ASF) under one - *or more contributor license agreements. See the NOTICE file - *distributed with this work for additional information - *regarding copyright ownership. The ASF licenses this file - *to you under the Apache License, Version 2.0 (the - *"License"); you may not use this file except in compliance - *with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - *Unless required by applicable law or agreed to in writing, - *software distributed under the License is distributed on an - *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - *specific language governing permissions and limitations - *under the License. - */ -/* - * shell_mediator.c - * - * \date Nov 4, 2012 - * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> - * \copyright Apache License, Version 2.0 - */ - -#include <stdlib.h> -#include <string.h> -#include <utils.h> -#include <shell.h> -#include <service_tracker.h> -#include <command.h> -#include <sys/socket.h> - -#include "log_helper.h" -#include "log_service.h" -#include "shell_mediator.h" - -static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service); -static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service); - -celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance) { - celix_status_t status = CELIX_SUCCESS; - service_tracker_customizer_pt customizer = NULL; - - (*instance) = (shell_mediator_pt) calloc(1, sizeof(**instance)); - if ((*instance) != NULL) { - - (*instance)->context = context; - (*instance)->tracker = NULL; - (*instance)->shellService = NULL; - - status = logHelper_create(context, &(*instance)->loghelper); - - status = CELIX_DO_IF(status, celixThreadMutex_create(&(*instance)->mutex, NULL)); - - status = CELIX_DO_IF(status, serviceTrackerCustomizer_create((*instance), NULL, shellMediator_addedService, - NULL, shellMediator_removedService, &customizer)); - status = CELIX_DO_IF(status, serviceTracker_create(context, (char * )OSGI_SHELL_SERVICE_NAME, customizer, &(*instance)->tracker)); - - if (status == CELIX_SUCCESS) { - logHelper_start((*instance)->loghelper); - serviceTracker_open((*instance)->tracker); - } - } else { - status = CELIX_ENOMEM; - } - - if ((status != CELIX_SUCCESS) && ((*instance) != NULL)){ - logHelper_log((*instance)->loghelper, OSGI_LOGSERVICE_ERROR, "Error creating shell_mediator, error code is %i\n", status); - } - return status; -} - -celix_status_t shellMediator_stop(shell_mediator_pt instance) { - service_tracker_pt tracker; - celixThreadMutex_lock(&instance->mutex); - tracker = instance->tracker; - celixThreadMutex_unlock(&instance->mutex); - - if (tracker != NULL) { - serviceTracker_close(tracker); - } - - return CELIX_SUCCESS; -} - -celix_status_t shellMediator_destroy(shell_mediator_pt instance) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadMutex_lock(&instance->mutex); - - instance->shellService = NULL; - serviceTracker_destroy(instance->tracker); - logHelper_stop(instance->loghelper); - status = logHelper_destroy(&instance->loghelper); - celixThreadMutex_destroy(&instance->mutex); - - - free(instance); - - - return status; -} - -celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err) { - celix_status_t status = CELIX_SUCCESS; - - celixThreadMutex_lock(&instance->mutex); - - - if (instance->shellService != NULL) { - instance->shellService->executeCommand(instance->shellService->shell, command, out, err); - } - - celixThreadMutex_unlock(&instance->mutex); - - return status; -} - -static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service) { - celix_status_t status = CELIX_SUCCESS; - shell_mediator_pt instance = (shell_mediator_pt) handler; - celixThreadMutex_lock(&instance->mutex); - instance->shellService = (shell_service_pt) service; - celixThreadMutex_unlock(&instance->mutex); - return status; -} - - -static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service) { - celix_status_t status = CELIX_SUCCESS; - shell_mediator_pt instance = (shell_mediator_pt) handler; - celixThreadMutex_lock(&instance->mutex); - instance->shellService = NULL; - celixThreadMutex_unlock(&instance->mutex); - return status; -} - http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/activator.c ---------------------------------------------------------------------- diff --git a/remote_shell/src/activator.c b/remote_shell/src/activator.c new file mode 100644 index 0000000..541eda6 --- /dev/null +++ b/remote_shell/src/activator.c @@ -0,0 +1,153 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * activator.c + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <celix_errno.h> + +#include <stdlib.h> + +#include "bundle_activator.h" +#include "bundle_context.h" + +#include "log_helper.h" +#include "connection_listener.h" +#include "shell_mediator.h" +#include "remote_shell.h" + +#define REMOTE_SHELL_TELNET_PORT_PROPERTY_NAME "remote.shell.telnet.port" +#define DEFAULT_REMOTE_SHELL_TELNET_PORT 6666 + +#define REMOTE_SHELL_TELNET_MAXCONN_PROPERTY_NAME "remote.shell.telnet.maxconn" +#define DEFAULT_REMOTE_SHELL_TELNET_MAXCONN 2 + +struct bundle_instance { + log_helper_pt loghelper; + shell_mediator_pt shellMediator; + remote_shell_pt remoteShell; + connection_listener_pt connectionListener; +}; + +typedef struct bundle_instance *bundle_instance_pt; + +static int bundleActivator_getPort(bundle_instance_pt bi, bundle_context_pt context); +static int bundleActivator_getMaximumConnections(bundle_instance_pt bi, bundle_context_pt context); +static int bundleActivator_getProperty(bundle_instance_pt bi, bundle_context_pt context, char * propertyName, int defaultValue); + +celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + + bundle_instance_pt bi = (bundle_instance_pt) calloc(1, sizeof(struct bundle_instance)); + + if (!bi) + { + status = CELIX_ENOMEM; + } + else if (userData != NULL) { + bi->shellMediator = NULL; + bi->remoteShell = NULL; + bi->connectionListener = NULL; + + status = logHelper_create(context, &bi->loghelper); + + (*userData) = bi; + } else { + status = CELIX_ILLEGAL_ARGUMENT; + free(bi); + } + + return status; +} + +celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + bundle_instance_pt bi = (bundle_instance_pt) userData; + + int port = bundleActivator_getPort(bi, context); + int maxConn = bundleActivator_getMaximumConnections(bi, context); + + status = logHelper_start(bi->loghelper); + + status = CELIX_DO_IF(status, shellMediator_create(context, &bi->shellMediator)); + status = CELIX_DO_IF(status, remoteShell_create(bi->shellMediator, maxConn, &bi->remoteShell)); + status = CELIX_DO_IF(status, connectionListener_create(bi->remoteShell, port, &bi->connectionListener)); + status = CELIX_DO_IF(status, connectionListener_start(bi->connectionListener)); + + return status; +} + +celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + bundle_instance_pt bi = (bundle_instance_pt) userData; + + connectionListener_stop(bi->connectionListener); + shellMediator_stop(bi->shellMediator); + shellMediator_destroy(bi->shellMediator); + + remoteShell_stopConnections(bi->remoteShell); + + status = logHelper_stop(bi->loghelper); + + return status; +} + +celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + bundle_instance_pt bi = (bundle_instance_pt) userData; + + connectionListener_destroy(bi->connectionListener); + status = logHelper_destroy(&bi->loghelper); + + return status; +} + +static int bundleActivator_getPort(bundle_instance_pt bi, bundle_context_pt context) { + return bundleActivator_getProperty(bi, context, REMOTE_SHELL_TELNET_PORT_PROPERTY_NAME, DEFAULT_REMOTE_SHELL_TELNET_PORT); +} + +static int bundleActivator_getMaximumConnections(bundle_instance_pt bi, bundle_context_pt context) { + return bundleActivator_getProperty(bi, context, REMOTE_SHELL_TELNET_MAXCONN_PROPERTY_NAME, DEFAULT_REMOTE_SHELL_TELNET_MAXCONN); +} + +static int bundleActivator_getProperty(bundle_instance_pt bi, bundle_context_pt context, char* propertyName, int defaultValue) { + const char *strValue = NULL; + int value; + + bundleContext_getProperty(context, propertyName, &strValue); + if (strValue != NULL) { + char* endptr = (char*)strValue; + + errno = 0; + value = strtol(strValue, &endptr, 10); + if (*endptr || errno != 0) { + logHelper_log(bi->loghelper, OSGI_LOGSERVICE_WARNING, "incorrect format for %s", propertyName); + value = defaultValue; + } + } + else { + value = defaultValue; + } + + return value; +} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/connection_listener.c ---------------------------------------------------------------------- diff --git a/remote_shell/src/connection_listener.c b/remote_shell/src/connection_listener.c new file mode 100644 index 0000000..3bef9e5 --- /dev/null +++ b/remote_shell/src/connection_listener.c @@ -0,0 +1,221 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * connection_listener.c + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdlib.h> +#include <string.h> +#include <celix_errno.h> +#include <stdio.h> +#include <errno.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <fcntl.h> + +#include "log_service.h" +#include "log_helper.h" + +#include "connection_listener.h" + +#include "shell_mediator.h" +#include "remote_shell.h" + +#define CONNECTION_LISTENER_TIMEOUT_SEC 5 + +struct connection_listener { + //constant + int port; + log_helper_pt* loghelper; + remote_shell_pt remoteShell; + celix_thread_mutex_t mutex; + + //protected by mutex + bool running; + celix_thread_t thread; + fd_set pollset; +}; + +static void* connection_listener_thread(void *data); + +celix_status_t connectionListener_create(remote_shell_pt remoteShell, int port, connection_listener_pt *instance) { + celix_status_t status = CELIX_SUCCESS; + (*instance) = calloc(1, sizeof(**instance)); + + if ((*instance) != NULL) { + (*instance)->port = port; + (*instance)->remoteShell = remoteShell; + (*instance)->running = false; + (*instance)->loghelper = remoteShell->loghelper; + + FD_ZERO(&(*instance)-> pollset); + + status = celixThreadMutex_create(&(*instance)->mutex, NULL); + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t connectionListener_start(connection_listener_pt instance) { + celix_status_t status = CELIX_SUCCESS; + celixThreadMutex_lock(&instance->mutex); + celixThread_create(&instance->thread, NULL, connection_listener_thread, instance); + celixThreadMutex_unlock(&instance->mutex); + return status; +} + +celix_status_t connectionListener_stop(connection_listener_pt instance) { + celix_status_t status = CELIX_SUCCESS; + celix_thread_t thread; + fd_set pollset; + + instance->running = false; + FD_ZERO(&pollset); + + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "CONNECTION_LISTENER: Stopping thread\n"); + + celixThreadMutex_lock(&instance->mutex); + thread = instance->thread; + + pollset = instance->pollset; + celixThreadMutex_unlock(&instance->mutex); + + celixThread_join(thread, NULL); + return status; +} + +celix_status_t connectionListener_destroy(connection_listener_pt instance) { + free(instance); + + return CELIX_SUCCESS; +} + +static void* connection_listener_thread(void *data) { + celix_status_t status = CELIX_BUNDLE_EXCEPTION; + connection_listener_pt instance = data; + struct timeval timeout; /* Timeout for select */ + fd_set active_fd_set; + FD_ZERO(&active_fd_set); + int listenSocket = 0; + int on = 1; + + struct addrinfo *result, *rp; + struct addrinfo hints; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_socktype = SOCK_STREAM; /* Datagram socket */ + hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ + hints.ai_protocol = 0; /* Any protocol */ + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + char portStr[10]; + snprintf(&portStr[0], 10, "%d", instance->port); + + getaddrinfo(NULL, portStr, &hints, &result); + + for (rp = result; rp != NULL && status == CELIX_BUNDLE_EXCEPTION; rp = rp->ai_next) { + + status = CELIX_BUNDLE_EXCEPTION; + + /* Create socket */ + listenSocket = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (listenSocket < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "Error creating socket: %s", strerror(errno)); + } + else if (setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "cannot set socket option: %s", strerror(errno)); + } + else if (bind(listenSocket, rp->ai_addr, rp->ai_addrlen) < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "cannot bind: %s", strerror(errno)); + } + else if (listen(listenSocket, 5) < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "listen failed: %s", strerror(errno)); + } + else { + status = CELIX_SUCCESS; + } + } + + if (status == CELIX_SUCCESS) { + + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "Remote Shell accepting connections on port %d", instance->port); + + celixThreadMutex_lock(&instance->mutex); + instance->pollset = active_fd_set; + celixThreadMutex_unlock(&instance->mutex); + + instance->running = true; + + while (status == CELIX_SUCCESS && instance->running) { + int selectRet = -1; + do { + timeout.tv_sec = CONNECTION_LISTENER_TIMEOUT_SEC; + timeout.tv_usec = 0; + + FD_ZERO(&active_fd_set); + FD_SET(listenSocket, &active_fd_set); + + selectRet = select(listenSocket + 1, &active_fd_set, NULL, NULL, &timeout); + } while (selectRet == -1 && errno == EINTR && instance->running == true); + if (selectRet < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "select on listenSocket failed: %s", strerror(errno)); + status = CELIX_BUNDLE_EXCEPTION; + } + else if (selectRet == 0) { + /* do nothing here */ + } + else if (FD_ISSET(listenSocket, &active_fd_set)) { + int acceptedSocket = accept(listenSocket, NULL, NULL); + + if (acceptedSocket < 0) { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_ERROR, "REMOTE_SHELL: accept failed: %s.", strerror(errno)); + status = CELIX_BUNDLE_EXCEPTION; + } + else { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_INFO, "REMOTE_SHELL: connection established."); + remoteShell_addConnection(instance->remoteShell, acceptedSocket); + } + } + else { + logHelper_log(*instance->loghelper, OSGI_LOGSERVICE_DEBUG, "REMOTE_SHELL: received data on a not-expected file-descriptor?"); + } + } + } + + if (listenSocket >= 0) { + close(listenSocket); + } + + freeaddrinfo(result); + + return NULL; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/connection_listener.h ---------------------------------------------------------------------- diff --git a/remote_shell/src/connection_listener.h b/remote_shell/src/connection_listener.h new file mode 100644 index 0000000..392d6ec --- /dev/null +++ b/remote_shell/src/connection_listener.h @@ -0,0 +1,42 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * connection_listener.h + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef connectionListener_H_ +#define connectionListener_H_ + +#include <bundle_context.h> +#include <celix_errno.h> + +#include "remote_shell.h" + +typedef struct connection_listener *connection_listener_pt; + +celix_status_t connectionListener_create(remote_shell_pt remoteShell, int port, connection_listener_pt *instance); +celix_status_t connectionListener_destroy(connection_listener_pt instance); +celix_status_t connectionListener_start(connection_listener_pt instance); +celix_status_t connectionListener_stop(connection_listener_pt instance); + +#endif /* connectionListener_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/remote_shell.c ---------------------------------------------------------------------- diff --git a/remote_shell/src/remote_shell.c b/remote_shell/src/remote_shell.c new file mode 100644 index 0000000..8f42778 --- /dev/null +++ b/remote_shell/src/remote_shell.c @@ -0,0 +1,242 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * remote_shell.c + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <utils.h> +#include <array_list.h> +#include <sys/socket.h> + +#include "log_helper.h" + +#include "log_service.h" +#include "remote_shell.h" + +#define COMMAND_BUFF_SIZE (256) + +#define RS_PROMPT ("-> ") +#define RS_WELCOME ("\n---- Apache Celix Remote Shell ----\n---- Type exit to disconnect ----\n\n-> ") +#define RS_GOODBYE ("Goobye!\n") +#define RS_ERROR ("Error executing command!\n") +#define RS_MAXIMUM_CONNECTIONS_REACHED ("Maximum number of connections reached. Disconnecting ...\n") + +#define CONNECTION_LISTENER_TIMEOUT_SEC 5 + + + +struct connection { + remote_shell_pt parent; + FILE *socketStream; + fd_set pollset; + bool threadRunning; +}; + +typedef struct connection *connection_pt; + +static celix_status_t remoteShell_connection_print(connection_pt connection, char * text); +static celix_status_t remoteShell_connection_execute(connection_pt connection, char *command); +static void* remoteShell_connection_run(void *data); + +celix_status_t remoteShell_create(shell_mediator_pt mediator, int maximumConnections, remote_shell_pt *instance) { + celix_status_t status = CELIX_SUCCESS; + (*instance) = calloc(1, sizeof(**instance)); + if ((*instance) != NULL) { + (*instance)->mediator = mediator; + (*instance)->maximumConnections = maximumConnections; + (*instance)->connections = NULL; + (*instance)->loghelper = &mediator->loghelper; + + status = celixThreadMutex_create(&(*instance)->mutex, NULL); + + if (status == CELIX_SUCCESS) { + status = arrayList_create(&(*instance)->connections); + } + } else { + status = CELIX_ENOMEM; + } + return status; +} + +celix_status_t remoteShell_destroy(remote_shell_pt instance) { + celix_status_t status = CELIX_SUCCESS; + + remoteShell_stopConnections(instance); + + celixThreadMutex_lock(&instance->mutex); + arrayList_destroy(instance->connections); + celixThreadMutex_unlock(&instance->mutex); + + return status; +} + +celix_status_t remoteShell_addConnection(remote_shell_pt instance, int socket) { + celix_status_t status = CELIX_SUCCESS; + connection_pt connection = calloc(1, sizeof(struct connection)); + + if (connection != NULL) { + connection->parent = instance; + connection->threadRunning = false; + connection->socketStream = fdopen(socket, "w"); + + if (connection->socketStream != NULL) { + + celixThreadMutex_lock(&instance->mutex); + + if (arrayList_size(instance->connections) < instance->maximumConnections) { + celix_thread_t connectionRunThread = celix_thread_default; + arrayList_add(instance->connections, connection); + status = celixThread_create(&connectionRunThread, NULL, &remoteShell_connection_run, connection); + } else { + status = CELIX_BUNDLE_EXCEPTION; + remoteShell_connection_print(connection, RS_MAXIMUM_CONNECTIONS_REACHED); + } + celixThreadMutex_unlock(&instance->mutex); + + } else { + status = CELIX_BUNDLE_EXCEPTION; + } + } else { + status = CELIX_ENOMEM; + } + + if (status != CELIX_SUCCESS && connection != NULL) { + if (connection->socketStream != NULL) { + fclose(connection->socketStream); + } + free(connection); + } + + return status; +} + +celix_status_t remoteShell_stopConnections(remote_shell_pt instance) { + celix_status_t status = CELIX_SUCCESS; + int length = 0; + int i = 0; + + celixThreadMutex_lock(&instance->mutex); + length = arrayList_size(instance->connections); + + for (i = 0; i < length; i += 1) { + connection_pt connection = arrayList_get(instance->connections, i); + connection->threadRunning = false; + } + + celixThreadMutex_unlock(&instance->mutex); + + return status; +} + +void *remoteShell_connection_run(void *data) { + celix_status_t status = CELIX_SUCCESS; + connection_pt connection = data; + size_t len; + int result; + struct timeval timeout; /* Timeout for select */ + + int fd = fileno(connection->socketStream); + + connection->threadRunning = true; + status = remoteShell_connection_print(connection, RS_WELCOME); + + while (status == CELIX_SUCCESS && connection->threadRunning == true) { + do { + timeout.tv_sec = CONNECTION_LISTENER_TIMEOUT_SEC; + timeout.tv_usec = 0; + + FD_ZERO(&connection->pollset); + FD_SET(fd, &connection->pollset); + result = select(fd + 1, &connection->pollset, NULL, NULL, &timeout); + } while (result == -1 && errno == EINTR && connection->threadRunning == true); + + /* The socket_fd has data available to be read */ + if (result > 0 && FD_ISSET(fd, &connection->pollset)) { + char buff[COMMAND_BUFF_SIZE]; + + len = recv(fd, buff, COMMAND_BUFF_SIZE - 1, 0); + if (len < COMMAND_BUFF_SIZE) { + celix_status_t commandStatus = CELIX_SUCCESS; + buff[len] = '\0'; + + commandStatus = remoteShell_connection_execute(connection, buff); + + if (commandStatus == CELIX_SUCCESS) { + remoteShell_connection_print(connection, RS_PROMPT); + } else if (commandStatus == CELIX_FILE_IO_EXCEPTION) { + //exit command + break; + } else { //error + remoteShell_connection_print(connection, RS_ERROR); + remoteShell_connection_print(connection, RS_PROMPT); + } + + } else { + logHelper_log(*connection->parent->loghelper, OSGI_LOGSERVICE_ERROR, "REMOTE_SHELL: Error while retrieving data"); + } + } + } + + remoteShell_connection_print(connection, RS_GOODBYE); + + logHelper_log(*connection->parent->loghelper, OSGI_LOGSERVICE_INFO, "REMOTE_SHELL: Closing socket"); + celixThreadMutex_lock(&connection->parent->mutex); + arrayList_removeElement(connection->parent->connections, connection); + celixThreadMutex_unlock(&connection->parent->mutex); + + fclose(connection->socketStream); + + return NULL; +} + +static celix_status_t remoteShell_connection_execute(connection_pt connection, char *command) { + celix_status_t status = CELIX_SUCCESS; + + if (status == CELIX_SUCCESS) { + char *dline = strdup(command); + char *line = utils_stringTrim(dline); + int len = strlen(line); + + if (len == 0) { + //ignore + } else if (len == 4 && strncmp("exit", line, 4) == 0) { + status = CELIX_FILE_IO_EXCEPTION; + } else { + status = shellMediator_executeCommand(connection->parent->mediator, line, connection->socketStream, connection->socketStream); + fflush(connection->socketStream); + } + + free(dline); + } + + return status; +} + +celix_status_t remoteShell_connection_print(connection_pt connection, char *text) { + size_t len = strlen(text); + int fd = fileno(connection->socketStream); + return (send(fd, text, len, 0) > 0) ? CELIX_SUCCESS : CELIX_FILE_IO_EXCEPTION; +} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/remote_shell.h ---------------------------------------------------------------------- diff --git a/remote_shell/src/remote_shell.h b/remote_shell/src/remote_shell.h new file mode 100644 index 0000000..55249a8 --- /dev/null +++ b/remote_shell/src/remote_shell.h @@ -0,0 +1,50 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * remote_shell.h + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef REMOTE_SHELL_H_ +#define REMOTE_SHELL_H_ + +#include <bundle_context.h> +#include <celix_errno.h> + +#include "shell_mediator.h" + +struct remote_shell { + log_helper_pt* loghelper; + shell_mediator_pt mediator; + celix_thread_mutex_t mutex; + int maximumConnections; + + array_list_pt connections; +}; +typedef struct remote_shell *remote_shell_pt; + +celix_status_t remoteShell_create(shell_mediator_pt mediator, int maximumConnections, remote_shell_pt *instance); +celix_status_t remoteShell_destroy(remote_shell_pt instance); +celix_status_t remoteShell_addConnection(remote_shell_pt instance, int socket); +celix_status_t remoteShell_stopConnections(remote_shell_pt instance); + +#endif /* REMOTE_SHELL_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/shell_mediator.c ---------------------------------------------------------------------- diff --git a/remote_shell/src/shell_mediator.c b/remote_shell/src/shell_mediator.c new file mode 100644 index 0000000..d9722a9 --- /dev/null +++ b/remote_shell/src/shell_mediator.c @@ -0,0 +1,139 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * shell_mediator.c + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stdlib.h> +#include <string.h> +#include <utils.h> +#include <shell.h> +#include <service_tracker.h> +#include <command.h> +#include <sys/socket.h> + +#include "log_helper.h" +#include "log_service.h" +#include "shell_mediator.h" + +static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service); +static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service); + +celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance) { + celix_status_t status = CELIX_SUCCESS; + service_tracker_customizer_pt customizer = NULL; + + (*instance) = (shell_mediator_pt) calloc(1, sizeof(**instance)); + if ((*instance) != NULL) { + + (*instance)->context = context; + (*instance)->tracker = NULL; + (*instance)->shellService = NULL; + + status = logHelper_create(context, &(*instance)->loghelper); + + status = CELIX_DO_IF(status, celixThreadMutex_create(&(*instance)->mutex, NULL)); + + status = CELIX_DO_IF(status, serviceTrackerCustomizer_create((*instance), NULL, shellMediator_addedService, + NULL, shellMediator_removedService, &customizer)); + status = CELIX_DO_IF(status, serviceTracker_create(context, (char * )OSGI_SHELL_SERVICE_NAME, customizer, &(*instance)->tracker)); + + if (status == CELIX_SUCCESS) { + logHelper_start((*instance)->loghelper); + serviceTracker_open((*instance)->tracker); + } + } else { + status = CELIX_ENOMEM; + } + + if ((status != CELIX_SUCCESS) && ((*instance) != NULL)){ + logHelper_log((*instance)->loghelper, OSGI_LOGSERVICE_ERROR, "Error creating shell_mediator, error code is %i\n", status); + } + return status; +} + +celix_status_t shellMediator_stop(shell_mediator_pt instance) { + service_tracker_pt tracker; + celixThreadMutex_lock(&instance->mutex); + tracker = instance->tracker; + celixThreadMutex_unlock(&instance->mutex); + + if (tracker != NULL) { + serviceTracker_close(tracker); + } + + return CELIX_SUCCESS; +} + +celix_status_t shellMediator_destroy(shell_mediator_pt instance) { + celix_status_t status = CELIX_SUCCESS; + + celixThreadMutex_lock(&instance->mutex); + + instance->shellService = NULL; + serviceTracker_destroy(instance->tracker); + logHelper_stop(instance->loghelper); + status = logHelper_destroy(&instance->loghelper); + celixThreadMutex_destroy(&instance->mutex); + + + free(instance); + + + return status; +} + +celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err) { + celix_status_t status = CELIX_SUCCESS; + + celixThreadMutex_lock(&instance->mutex); + + + if (instance->shellService != NULL) { + instance->shellService->executeCommand(instance->shellService->shell, command, out, err); + } + + celixThreadMutex_unlock(&instance->mutex); + + return status; +} + +static celix_status_t shellMediator_addedService(void *handler, service_reference_pt reference, void * service) { + celix_status_t status = CELIX_SUCCESS; + shell_mediator_pt instance = (shell_mediator_pt) handler; + celixThreadMutex_lock(&instance->mutex); + instance->shellService = (shell_service_pt) service; + celixThreadMutex_unlock(&instance->mutex); + return status; +} + + +static celix_status_t shellMediator_removedService(void *handler, service_reference_pt reference, void * service) { + celix_status_t status = CELIX_SUCCESS; + shell_mediator_pt instance = (shell_mediator_pt) handler; + celixThreadMutex_lock(&instance->mutex); + instance->shellService = NULL; + celixThreadMutex_unlock(&instance->mutex); + return status; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/remote_shell/src/shell_mediator.h ---------------------------------------------------------------------- diff --git a/remote_shell/src/shell_mediator.h b/remote_shell/src/shell_mediator.h new file mode 100644 index 0000000..24e8250 --- /dev/null +++ b/remote_shell/src/shell_mediator.h @@ -0,0 +1,54 @@ +/** + *Licensed to the Apache Software Foundation (ASF) under one + *or more contributor license agreements. See the NOTICE file + *distributed with this work for additional information + *regarding copyright ownership. The ASF licenses this file + *to you under the Apache License, Version 2.0 (the + *"License"); you may not use this file except in compliance + *with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + *Unless required by applicable law or agreed to in writing, + *software distributed under the License is distributed on an + *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + *specific language governing permissions and limitations + *under the License. + */ +/* + * shell_mediator.h + * + * \date Nov 4, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + + +#ifndef shellMediator_H_ +#define shellMediator_H_ + +#include <bundle_context.h> +#include <service_tracker.h> +#include <celix_errno.h> + +#include <shell.h> + +struct shell_mediator { + + log_helper_pt loghelper; + bundle_context_pt context; + service_tracker_pt tracker; + celix_thread_mutex_t mutex; + + //protected by mutex + shell_service_pt shellService; +}; +typedef struct shell_mediator *shell_mediator_pt; + +celix_status_t shellMediator_create(bundle_context_pt context, shell_mediator_pt *instance); +celix_status_t shellMediator_stop(shell_mediator_pt instance); +celix_status_t shellMediator_destroy(shell_mediator_pt instance); +celix_status_t shellMediator_executeCommand(shell_mediator_pt instance, char *command, FILE *out, FILE *err); + +#endif /* shellMediator_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/shell/CMakeLists.txt ---------------------------------------------------------------------- diff --git a/shell/CMakeLists.txt b/shell/CMakeLists.txt index 974d2ff..31822c4 100644 --- a/shell/CMakeLists.txt +++ b/shell/CMakeLists.txt @@ -18,38 +18,35 @@ celix_subproject(SHELL "Option to enable building the Shell bundles" ON DEPS LAU if (SHELL) find_package(CURL REQUIRED) + add_library(shell_api INTERFACE) + target_include_directories(shell_api INTERFACE include) + add_bundle(shell SYMBOLIC_NAME "apache_celix_shell" VERSION "2.0.0" NAME "Apache Celix Shell" - SOURCES + src/activator + src/shell + src/lb_command + src/start_command + src/stop_command + src/install_command + src/update_command + src/uninstall_command + src/log_command + src/inspect_command + src/help_command + ) + target_include_directories(shell PRIVATE src ${CURL_INCLUDE_DIRS}) + target_link_libraries(shell PRIVATE Celix::shell_api ${CURL_LIBRARIES} Celix::log_service_api log_helper) - private/src/activator - private/src/shell - private/src/lb_command - private/src/start_command - private/src/stop_command - private/src/install_command - private/src/update_command - private/src/uninstall_command - private/src/log_command - private/src/inspect_command - private/src/help_command - - ${PROJECT_SOURCE_DIR}/log_service/public/src/log_helper.c - - ) - - install_bundle(shell + install_bundle(shell HEADERS - public/include/shell.h public/include/command.h public/include/shell_constants.h - ) + include/shell.h include/command.h include/shell_constants.h + ) - include_directories("public/include") - include_directories("private/include") - include_directories("${PROJECT_SOURCE_DIR}/utils/public/include") - include_directories("${PROJECT_SOURCE_DIR}/log_service/public/include") - include_directories(${CURL_INCLUDE_DIRS}) - target_link_libraries(shell celix_framework ${CURL_LIBRARIES}) + #Setup target aliases to match external usage + add_library(Celix::shell_api ALIAS shell_api) + add_library(Celix::shell ALIAS shell) endif (SHELL)
