http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/deployment_admin.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/deployment_admin.c b/deployment_admin/src/deployment_admin.c new file mode 100644 index 0000000..17e78db --- /dev/null +++ b/deployment_admin/src/deployment_admin.c @@ -0,0 +1,809 @@ +/** + *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. + */ +/* + * deployment_admin.c + * + * \date Nov 7, 2011 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <stdint.h> + +#include <dirent.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include <curl/curl.h> +#include <curl/easy.h> + +#include <uuid/uuid.h> + +#include "celixbool.h" +#include "deployment_admin.h" +#include "celix_errno.h" +#include "bundle_context.h" +#include "constants.h" +#include "deployment_package.h" +#include "bundle.h" +#include "utils.h" + +#include "log.h" +#include "log_store.h" +#include "log_sync.h" + +#include "resource_processor.h" +#include "miniunz.h" + +#define IDENTIFICATION_ID "deployment_admin_identification" +#define DEFAULT_IDENTIFICATION_ID "celix" + +#define ADMIN_URL "deployment_admin_url" +#define DEFAULT_ADMIN_URL "localhost:8080" + +#define DEPLOYMENT_CACHE_DIR "deployment_cache_dir" +#define DEPLOYMENT_TAGS "deployment_tags" +// "http://localhost:8080/deployment/" + +#define VERSIONS "/versions" + +static void* deploymentAdmin_poll(void *deploymentAdmin); +celix_status_t deploymentAdmin_download(deployment_admin_pt admin, char * url, char **inputFile); +size_t deploymentAdmin_writeData(void *ptr, size_t size, size_t nmemb, FILE *stream); +static celix_status_t deploymentAdmin_deleteTree(char * directory); +celix_status_t deploymentAdmin_readVersions(deployment_admin_pt admin, array_list_pt versions); + +celix_status_t deploymentAdmin_stopDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt target); +celix_status_t deploymentAdmin_updateDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source); +celix_status_t deploymentAdmin_startDeploymentPackageCustomizerBundles(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target); +celix_status_t deploymentAdmin_processDeploymentPackageResources(deployment_admin_pt admin, deployment_package_pt source); +celix_status_t deploymentAdmin_dropDeploymentPackageResources(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target); +celix_status_t deploymentAdmin_dropDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target); +celix_status_t deploymentAdmin_startDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source); + +static celix_status_t deploymentAdmin_performRequest(deployment_admin_pt admin, char* entry); +static celix_status_t deploymentAdmin_auditEventTargetPropertiesSet(deployment_admin_pt admin); +static celix_status_t deploymentAdmin_auditEventFrameworkStarted(deployment_admin_pt admin); + +celix_status_t deploymentAdmin_create(bundle_context_pt context, deployment_admin_pt *admin) { + celix_status_t status = CELIX_SUCCESS; + + *admin = calloc(1, sizeof(**admin)); + if (!*admin) { + status = CELIX_ENOMEM; + } else { + (*admin)->running = true; + (*admin)->context = context; + (*admin)->current = NULL; + (*admin)->packages = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + (*admin)->targetIdentification = NULL; + (*admin)->pollUrl = NULL; + (*admin)->auditlogUrl = NULL; + + bundleContext_getProperty(context, IDENTIFICATION_ID, (const char**) &(*admin)->targetIdentification); + if ((*admin)->targetIdentification == NULL) { + (*admin)->targetIdentification = DEFAULT_IDENTIFICATION_ID; + fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Identification ID not set, using default '%s'. Set id by using '%s'", + DEFAULT_IDENTIFICATION_ID, IDENTIFICATION_ID); + } + + struct timeval tv; + gettimeofday(&tv,NULL); + (*admin)->auditlogId = tv.tv_sec*(uint64_t)1000000+tv.tv_usec; + (*admin)->aditlogSeqNr = 0; + + if ((*admin)->targetIdentification == NULL ) { + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Target name must be set using \"deployment_admin_identification\""); + } else { + const char *url = NULL; + bundleContext_getProperty(context, ADMIN_URL, &url); + if (url == NULL) { + url = DEFAULT_ADMIN_URL; + fw_log(logger, OSGI_FRAMEWORK_LOG_INFO, "Server URL is not set, using default '%s'. Set id by using '%s'", + DEFAULT_ADMIN_URL, ADMIN_URL); + } + + int pollUrlLength = strlen(url) + strlen((*admin)->targetIdentification) + strlen(VERSIONS) + 13; + int auditlogUrlLength = strlen(url) + 10; + + char pollUrl[pollUrlLength]; + char auditlogUrl[auditlogUrlLength]; + + snprintf(pollUrl, pollUrlLength, "%s/deployment/%s%s", url, (*admin)->targetIdentification, VERSIONS); + snprintf(auditlogUrl, auditlogUrlLength, "%s/auditlog", url); + + (*admin)->pollUrl = strdup(pollUrl); + (*admin)->auditlogUrl = strdup(auditlogUrl); + +// log_store_pt store = NULL; +// log_pt log = NULL; +// log_sync_pt sync = NULL; +// logStore_create(subpool, &store); +// log_create(subpool, store, &log); +// logSync_create(subpool, (*admin)->targetIdentification, store, &sync); +// +// log_log(log, 20000, NULL); + + + celixThread_create(&(*admin)->poller, NULL, deploymentAdmin_poll, *admin); + } + } + + return status; +} + + + +celix_status_t deploymentAdmin_destroy(deployment_admin_pt admin) { + celix_status_t status = CELIX_SUCCESS; + + admin->running = false; + + celixThread_join(admin->poller, NULL); + + hash_map_iterator_pt iter = hashMapIterator_create(admin->packages); + + while (hashMapIterator_hasNext(iter)) { + deployment_package_pt target = (deployment_package_pt) hashMapIterator_nextValue(iter); + deploymentPackage_destroy(target); + } + + hashMapIterator_destroy(iter); + + hashMap_destroy(admin->packages, false, false); + + if (admin->current != NULL) { + free(admin->current); + } + + free(admin->pollUrl); + free(admin->auditlogUrl); + + free(admin); + + return status; +} + + +static celix_status_t deploymentAdmin_performRequest(deployment_admin_pt admin, char* entry) { + celix_status_t status = CELIX_SUCCESS; + + CURL *curl; + CURLcode res; + curl = curl_easy_init(); + + if (!curl) { + status = CELIX_BUNDLE_EXCEPTION; + + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error initializing curl."); + } + + char url[strlen(admin->auditlogUrl)+6]; + sprintf(url, "%s/send", admin->auditlogUrl); + + if (status == CELIX_SUCCESS) { + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, entry); + res = curl_easy_perform(curl); + + if (res != CURLE_OK ) { + status = CELIX_BUNDLE_EXCEPTION; + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error sending auditlog, got curl error code %d", res); + } + } + + return status; +} + +static celix_status_t deploymentAdmin_auditEventTargetPropertiesSet(deployment_admin_pt admin) { + celix_status_t status = CELIX_SUCCESS; + + const char *tags = NULL; + + bundleContext_getProperty(admin->context, DEPLOYMENT_TAGS, &tags); + + if (tags != NULL) { + char entry[512]; + int entrySize = 0; + + entrySize = snprintf(entry, 512, "%s,%llu,%u,0,%i,%s\n", admin->targetIdentification, admin->auditlogId, admin->aditlogSeqNr++, DEPLOYMENT_ADMIN_AUDIT_EVENT__TARGETPROPERTIES_SET, tags); + + if (entrySize >= 512) { + status = CELIX_BUNDLE_EXCEPTION; + } + else { + status = deploymentAdmin_performRequest(admin, entry); + } + } + + return status; +} + +static celix_status_t deploymentAdmin_auditEventFrameworkStarted(deployment_admin_pt admin) { + celix_status_t status = CELIX_SUCCESS; + + char entry[512]; + int entrySize = 0; + + entrySize = snprintf(entry, 512, "%s,%llu,%u,0,%i\n", admin->targetIdentification, admin->auditlogId, admin->aditlogSeqNr++, DEPLOYMENT_ADMIN_AUDIT_EVENT__FRAMEWORK_STARTED); + + if (entrySize >= 512) { + status = CELIX_BUNDLE_EXCEPTION; + } + else { + status = deploymentAdmin_performRequest(admin, entry); + } + + return status; +} + + +static void *deploymentAdmin_poll(void *deploymentAdmin) { + deployment_admin_pt admin = deploymentAdmin; + + /*first poll send framework started audit event, note this will register the target in Apache ACE*/ + deploymentAdmin_auditEventFrameworkStarted(admin); + deploymentAdmin_auditEventTargetPropertiesSet(admin); + + while (admin->running) { + int i; + + //poll ace + array_list_pt versions = NULL; + arrayList_create(&versions); + + deploymentAdmin_readVersions(admin, versions); + + char *last = arrayList_get(versions, arrayList_size(versions) - 1); + + if (last != NULL) { + if (admin->current == NULL || strcmp(last, admin->current) != 0) { + int length = strlen(admin->pollUrl) + strlen(last) + 2; + char request[length]; + + // TODO + // We do not yet support fix packages + // Check string lenght! + // snprintf(request, length, "%s/%s?current=%s", admin->pollUrl, last, admin->current); + snprintf(request, length, "%s/%s", admin->pollUrl, last); + + char *inputFilename = NULL; + celix_status_t status = deploymentAdmin_download(admin ,request, &inputFilename); + if (status == CELIX_SUCCESS) { + bundle_pt bundle = NULL; + bundleContext_getBundle(admin->context, &bundle); + char *entry = NULL; + bundle_getEntry(bundle, "/", &entry); + + // Handle file + char tmpDir[256]; + char uuid[37]; + uuid_t uid; + uuid_generate(uid); + uuid_unparse(uid, uuid); + snprintf(tmpDir, 256, "%s%s", entry, uuid); + if( mkdir(tmpDir, S_IRWXU) == -1){ + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed creating directory %s",tmpDir); + } + + // TODO: update to use bundle cache DataFile instead of module entries. + unzip_extractDeploymentPackage(inputFilename, tmpDir); + int length = strlen(tmpDir) + 22; + char manifest[length]; + snprintf(manifest, length, "%s/META-INF/MANIFEST.MF", tmpDir); + manifest_pt mf = NULL; + manifest_createFromFile(manifest, &mf); + deployment_package_pt source = NULL; + deploymentPackage_create(admin->context, mf, &source); + const char *name = NULL; + deploymentPackage_getName(source, &name); + + int repoDirLength = strlen(entry) + 5; + char repoDir[repoDirLength]; + snprintf(repoDir, repoDirLength, "%srepo", entry); + if( mkdir(repoDir, S_IRWXU) == -1){ + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Failed creating directory %s",repoDir); + } + + int repoCacheLength = strlen(entry) + strlen(name) + 6; + char repoCache[repoCacheLength]; + snprintf(repoCache, repoCacheLength, "%srepo/%s", entry, name); + deploymentAdmin_deleteTree(repoCache); + int stat = rename(tmpDir, repoCache); + if (stat != 0) { + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "No success"); + } + + deployment_package_pt target = hashMap_get(admin->packages, name); + if (target == NULL) { +// target = empty package + } + + deploymentAdmin_stopDeploymentPackageBundles(admin, target); + deploymentAdmin_updateDeploymentPackageBundles(admin, source); + deploymentAdmin_startDeploymentPackageCustomizerBundles(admin, source, target); + deploymentAdmin_processDeploymentPackageResources(admin, source); + deploymentAdmin_dropDeploymentPackageResources(admin, source, target); + deploymentAdmin_dropDeploymentPackageBundles(admin, source, target); + deploymentAdmin_startDeploymentPackageBundles(admin, source); + + deploymentAdmin_deleteTree(repoCache); + deploymentAdmin_deleteTree(tmpDir); + if( remove(inputFilename) == -1){ + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Remove of %s failed",inputFilename); + } + admin->current = strdup(last); + hashMap_put(admin->packages, (char*)name, source); + + free(entry); + } + if (inputFilename != NULL) { + free(inputFilename); + } + } + } + + sleep(5); + + for (i = arrayList_size(versions); i > 0; --i) { + free(arrayList_remove(versions, 0)); + } + + arrayList_destroy(versions); + } + + return NULL; +} + +struct MemoryStruct { + char *memory; + size_t size; +}; + +size_t deploymentAdmin_parseVersions(void *contents, size_t size, size_t nmemb, void *userp) { + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->memory = realloc(mem->memory, mem->size + realsize + 1); + if (mem->memory == NULL) { + /* out of memory! */ + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "not enough memory (realloc returned NULL)"); + exit(EXIT_FAILURE); + } + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + + return realsize; +} + +celix_status_t deploymentAdmin_readVersions(deployment_admin_pt admin, array_list_pt versions) { + celix_status_t status = CELIX_SUCCESS; + + CURL *curl; + CURLcode res; + curl = curl_easy_init(); + struct MemoryStruct chunk; + chunk.memory = calloc(1, sizeof(char)); + chunk.size = 0; + if (curl) { + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_URL, admin->pollUrl); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deploymentAdmin_parseVersions); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + status = CELIX_BUNDLE_EXCEPTION; + } + /* always cleanup */ + curl_easy_cleanup(curl); + + char *last; + char *token = strtok_r(chunk.memory, "\n", &last); + while (token != NULL) { + arrayList_add(versions, strdup(token)); + token = strtok_r(NULL, "\n", &last); + } + } + + if (chunk.memory) { + free(chunk.memory); + } + + return status; +} + + +celix_status_t deploymentAdmin_download(deployment_admin_pt admin, char * url, char **inputFile) { + celix_status_t status = CELIX_SUCCESS; + CURL *curl = NULL; + CURLcode res = 0; + curl = curl_easy_init(); + if (curl) { + const char *dir = NULL; + bundleContext_getProperty(admin->context, DEPLOYMENT_CACHE_DIR, &dir); + if (dir != NULL) { + *inputFile = calloc(1024, sizeof (char)); + snprintf(*inputFile, 1024, "%s/%s", dir, "updateXXXXXX"); + } + else { + *inputFile = strdup("updateXXXXXX"); + } + umask(0011); + int fd = mkstemp(*inputFile); + if (fd != -1) { + FILE *fp = fopen(*inputFile, "wb+"); + if(fp!=NULL){ + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deploymentAdmin_writeData); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); + //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + //curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, updateCommand_downloadProgress); + res = curl_easy_perform(curl); + + /* always cleanup */ + curl_easy_cleanup(curl); + fclose(fp); + } + else{ + status = CELIX_FILE_IO_EXCEPTION; + } + } + else{ + status = CELIX_FILE_IO_EXCEPTION; + } + } + else{ + res = CURLE_FAILED_INIT; + } + + if (res != CURLE_OK) { + *inputFile[0] = '\0'; + status = CELIX_ILLEGAL_STATE; + } + + return status; +} + +size_t deploymentAdmin_writeData(void *ptr, size_t size, size_t nmemb, FILE *stream) { + size_t written = fwrite(ptr, size, nmemb, stream); + return written; +} + + +static celix_status_t deploymentAdmin_deleteTree(char * directory) { + DIR *dir; + celix_status_t status = CELIX_SUCCESS; + dir = opendir(directory); + if (dir == NULL) { + status = CELIX_FILE_IO_EXCEPTION; + } else { + + struct dirent* dent = NULL; + + errno = 0; + dent = readdir(dir); + while (errno == 0 && dent != NULL) { + if ((strcmp((dent->d_name), ".") != 0) && (strcmp((dent->d_name), "..") != 0)) { + char subdir[512]; + snprintf(subdir, sizeof(subdir), "%s/%s", directory, dent->d_name); + + if (dent->d_type == DT_DIR) { + status = deploymentAdmin_deleteTree(subdir); + } else { + if (remove(subdir) != 0) { + status = CELIX_FILE_IO_EXCEPTION; + break; + } + } + } + + errno = 0; + dent = readdir(dir); + } + + if (errno != 0) { + status = CELIX_FILE_IO_EXCEPTION; + } else if (closedir(dir) != 0) { + status = CELIX_FILE_IO_EXCEPTION; + } else if (rmdir(directory) != 0) { + status = CELIX_FILE_IO_EXCEPTION; + } + } + + framework_logIfError(logger, status, NULL, "Failed to delete tree"); + + return status; +} + +celix_status_t deploymentAdmin_stopDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt target) { + celix_status_t status = CELIX_SUCCESS; + + if (target != NULL) { + array_list_pt infos = NULL; + deploymentPackage_getBundleInfos(target, &infos); + int i; + for (i = 0; i < arrayList_size(infos); i++) { + bundle_pt bundle = NULL; + bundle_info_pt info = arrayList_get(infos, i); + deploymentPackage_getBundle(target, info->symbolicName, &bundle); + if (bundle != NULL) { + bundle_stop(bundle); + } else { + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "DEPLOYMENT_ADMIN: Bundle %s not found", info->symbolicName); + } + } + arrayList_destroy(infos); + } + + return status; +} + +celix_status_t deploymentAdmin_updateDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source) { + celix_status_t status = CELIX_SUCCESS; + + array_list_pt infos = NULL; + deploymentPackage_getBundleInfos(source, &infos); + int i; + for (i = 0; i < arrayList_size(infos); i++) { + bundle_pt bundle = NULL; + bundle_info_pt info = arrayList_get(infos, i); + + bundleContext_getBundle(admin->context, &bundle); + char *entry = NULL; + bundle_getEntry(bundle, "/", &entry); + const char *name = NULL; + deploymentPackage_getName(source, &name); + + int bundlePathLength = strlen(entry) + strlen(name) + strlen(info->path) + 7; + int bsnLength = strlen(info->symbolicName) + 9; + + char bundlePath[bundlePathLength]; + snprintf(bundlePath, bundlePathLength, "%srepo/%s/%s", entry, name, info->path); + + char bsn[bsnLength]; + snprintf(bsn, bsnLength, "osgi-dp:%s", info->symbolicName); + + bundle_pt updateBundle = NULL; + deploymentPackage_getBundle(source, info->symbolicName, &updateBundle); + if (updateBundle != NULL) { + //printf("Update bundle from: %s\n", bundlePath); + bundle_update(updateBundle, bundlePath); + } else { + //printf("Install bundle from: %s\n", bundlePath); + bundleContext_installBundle2(admin->context, bsn, bundlePath, &updateBundle); + } + + free(entry); + } + arrayList_destroy(infos); + return status; +} + +celix_status_t deploymentAdmin_startDeploymentPackageCustomizerBundles(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target) { + celix_status_t status = CELIX_SUCCESS; + + array_list_pt bundles = NULL; + array_list_pt sourceInfos = NULL; + + arrayList_create(&bundles); + + deploymentPackage_getBundleInfos(source, &sourceInfos); + int i; + for (i = 0; i < arrayList_size(sourceInfos); i++) { + bundle_info_pt sourceInfo = arrayList_get(sourceInfos, i); + if (sourceInfo->customizer) { + bundle_pt bundle = NULL; + deploymentPackage_getBundle(source, sourceInfo->symbolicName, &bundle); + if (bundle != NULL) { + arrayList_add(bundles, bundle); + } + } + } + arrayList_destroy(sourceInfos); + + if (target != NULL) { + array_list_pt targetInfos = NULL; + deploymentPackage_getBundleInfos(target, &targetInfos); + for (i = 0; i < arrayList_size(targetInfos); i++) { + bundle_info_pt targetInfo = arrayList_get(targetInfos, i); + if (targetInfo->customizer) { + bundle_pt bundle = NULL; + deploymentPackage_getBundle(target, targetInfo->symbolicName, &bundle); + if (bundle != NULL) { + arrayList_add(bundles, bundle); + } + } + } + arrayList_destroy(targetInfos); + } + + for (i = 0; i < arrayList_size(bundles); i++) { + bundle_pt bundle = arrayList_get(bundles, i); + bundle_start(bundle); + } + + arrayList_destroy(bundles); + + return status; +} + +celix_status_t deploymentAdmin_processDeploymentPackageResources(deployment_admin_pt admin, deployment_package_pt source) { + celix_status_t status = CELIX_SUCCESS; + + array_list_pt infos = NULL; + deploymentPackage_getResourceInfos(source, &infos); + int i; + for (i = 0; i < arrayList_size(infos); i++) { + resource_info_pt info = arrayList_get(infos, i); + array_list_pt services = NULL; + int length = strlen(OSGI_FRAMEWORK_SERVICE_PID) + strlen(info->resourceProcessor) + 4; + char filter[length]; + + snprintf(filter, length, "(%s=%s)", OSGI_FRAMEWORK_SERVICE_PID, info->resourceProcessor); + + status = bundleContext_getServiceReferences(admin->context, DEPLOYMENTADMIN_RESOURCE_PROCESSOR_SERVICE, filter, &services); + if (status == CELIX_SUCCESS) { + if (services != NULL && arrayList_size(services) > 0) { + service_reference_pt ref = arrayList_get(services, 0); + // In Felix a check is done to assure the processor belongs to the deployment package + // Is this according to spec? + void *processorP = NULL; + status = bundleContext_getService(admin->context, ref, &processorP); + if (status == CELIX_SUCCESS) { + bundle_pt bundle = NULL; + char *entry = NULL; + const char *name = NULL; + const char *packageName = NULL; + resource_processor_service_pt processor = processorP; + + bundleContext_getBundle(admin->context, &bundle); + bundle_getEntry(bundle, "/", &entry); + deploymentPackage_getName(source, &name); + + int length = strlen(entry) + strlen(name) + strlen(info->path) + 7; + char resourcePath[length]; + snprintf(resourcePath, length, "%srepo/%s/%s", entry, name, info->path); + deploymentPackage_getName(source, &packageName); + + processor->begin(processor->processor, (char*)packageName); + processor->process(processor->processor, info->path, resourcePath); + + free(entry); + } + } + } + + if(services != NULL) { + arrayList_destroy(services); + } + } + + arrayList_destroy(infos); + + + return status; +} + +celix_status_t deploymentAdmin_dropDeploymentPackageResources(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target) { + celix_status_t status = CELIX_SUCCESS; + + if (target != NULL) { + array_list_pt infos = NULL; + deploymentPackage_getResourceInfos(target, &infos); + int i; + for (i = 0; i < arrayList_size(infos); i++) { + resource_info_pt info = arrayList_get(infos, i); + resource_info_pt sourceInfo = NULL; + deploymentPackage_getResourceInfoByPath(source, info->path, &sourceInfo); + if (sourceInfo == NULL) { + array_list_pt services = NULL; + int length = strlen(OSGI_FRAMEWORK_SERVICE_PID) + strlen(info->resourceProcessor) + 4; + char filter[length]; + + snprintf(filter, length, "(%s=%s)", OSGI_FRAMEWORK_SERVICE_PID, info->resourceProcessor); + status = bundleContext_getServiceReferences(admin->context, DEPLOYMENTADMIN_RESOURCE_PROCESSOR_SERVICE, filter, &services); + if (status == CELIX_SUCCESS) { + if (services != NULL && arrayList_size(services) > 0) { + service_reference_pt ref = arrayList_get(services, 0); + // In Felix a check is done to assure the processor belongs to the deployment package + // Is this according to spec? + void *processorP = NULL; + status = bundleContext_getService(admin->context, ref, &processorP); + if (status == CELIX_SUCCESS) { + const char *packageName = NULL; + resource_processor_service_pt processor = processorP; + + deploymentPackage_getName(source, &packageName); + processor->begin(processor->processor, (char*)packageName); + processor->dropped(processor->processor, info->path); + } + } + } + + if (services != NULL) { + arrayList_destroy(services); + } + + } + } + + arrayList_destroy(infos); + } + + return status; +} + +celix_status_t deploymentAdmin_dropDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source, deployment_package_pt target) { + celix_status_t status = CELIX_SUCCESS; + + if (target != NULL) { + array_list_pt targetInfos = NULL; + deploymentPackage_getBundleInfos(target, &targetInfos); + int i; + for (i = 0; i < arrayList_size(targetInfos); i++) { + bundle_info_pt targetInfo = arrayList_get(targetInfos, i); + if (!targetInfo->customizer) { + bundle_info_pt info = NULL; + deploymentPackage_getBundleInfoByName(source, targetInfo->symbolicName, &info); + if (info == NULL) { + bundle_pt bundle = NULL; + deploymentPackage_getBundle(target, targetInfo->symbolicName, &bundle); + bundle_uninstall(bundle); + } + } + } + arrayList_destroy(targetInfos); + } + + return status; +} + +celix_status_t deploymentAdmin_startDeploymentPackageBundles(deployment_admin_pt admin, deployment_package_pt source) { + celix_status_t status = CELIX_SUCCESS; + + array_list_pt infos = NULL; + deploymentPackage_getBundleInfos(source, &infos); + int i; + for (i = 0; i < arrayList_size(infos); i++) { + bundle_pt bundle = NULL; + bundle_info_pt info = arrayList_get(infos, i); + if (!info->customizer) { + deploymentPackage_getBundle(source, info->symbolicName, &bundle); + if (bundle != NULL) { + bundle_start(bundle); + } else { + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "DEPLOYMENT_ADMIN: Could not start bundle %s", info->symbolicName); + } + } + } + arrayList_destroy(infos); + + return status; +}
http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/deployment_admin.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/deployment_admin.h b/deployment_admin/src/deployment_admin.h new file mode 100644 index 0000000..a7e3a39 --- /dev/null +++ b/deployment_admin/src/deployment_admin.h @@ -0,0 +1,57 @@ +/** + *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. + */ +/* + * deployment_admin.h + * + * \date Nov 7, 2011 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef DEPLOYMENT_ADMIN_H_ +#define DEPLOYMENT_ADMIN_H_ + +#include "bundle_context.h" + +typedef struct deployment_admin *deployment_admin_pt; + +struct deployment_admin { + celix_thread_t poller; + bundle_context_pt context; + + bool running; + char *current; + hash_map_pt packages; + char *targetIdentification; + char *pollUrl; + char *auditlogUrl; + unsigned long long auditlogId; + unsigned int aditlogSeqNr; +}; + +typedef enum { + DEPLOYMENT_ADMIN_AUDIT_EVENT__FRAMEWORK_STARTED = 1005, + DEPLOYMENT_ADMIN_AUDIT_EVENT__TARGETPROPERTIES_SET = 4001 + +} DEPLOYMENT_ADMIN_AUDIT_EVENT; + +celix_status_t deploymentAdmin_create(bundle_context_pt context, deployment_admin_pt *admin); +celix_status_t deploymentAdmin_destroy(deployment_admin_pt admin); + +#endif /* DEPLOYMENT_ADMIN_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/deployment_admin_activator.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/deployment_admin_activator.c b/deployment_admin/src/deployment_admin_activator.c new file mode 100644 index 0000000..93fd6b5 --- /dev/null +++ b/deployment_admin/src/deployment_admin_activator.c @@ -0,0 +1,78 @@ +/** + *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. + */ +/* + * deployment_admin_activator.c + * + * \date Nov 7, 2011 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ +#include <stdlib.h> + +#include "bundle_activator.h" +#include "deployment_admin.h" + +struct bundle_activator { + deployment_admin_pt admin; +}; + +typedef struct bundle_activator* bundle_activator_pt; + +celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) { + celix_status_t status = CELIX_SUCCESS; + + bundle_activator_pt activator = NULL; + + activator = calloc(1, sizeof(*activator)); + if (!activator) { + status = CELIX_ENOMEM; + } else { + status = deploymentAdmin_create(context, &activator->admin); + + *userData = activator; + } + + return status; +} + +celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + + return status; +} + +celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context) { + celix_status_t status = CELIX_SUCCESS; + + return status; +} + +celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context) { + celix_status_t status; + + bundle_activator_pt activator = (bundle_activator_pt) userData; + + status = deploymentAdmin_destroy(activator->admin); + + free(activator); + + return status; +} + + http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/deployment_package.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/deployment_package.c b/deployment_admin/src/deployment_package.c new file mode 100644 index 0000000..1520db8 --- /dev/null +++ b/deployment_admin/src/deployment_package.c @@ -0,0 +1,219 @@ +/** + *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. + */ +/* + * deployment_package.c + * + * \date Nov 8, 2011 + * \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 "deployment_package.h" +#include "constants.h" +#include "utils.h" +#include "bundle_context.h" +#include "module.h" +#include "bundle.h" + +static const char * const RESOURCE_PROCESSOR = "Resource-Processor"; +static const char * const DEPLOYMENTPACKAGE_CUSTOMIZER = "DeploymentPackage-Customizer"; + +celix_status_t deploymentPackage_processEntries(deployment_package_pt package); +static celix_status_t deploymentPackage_isBundleResource(properties_pt attributes, bool *isBundleResource); +static celix_status_t deploymentPackage_parseBooleanHeader(const char *value, bool *boolValue); + +celix_status_t deploymentPackage_create(bundle_context_pt context, manifest_pt manifest, deployment_package_pt *package) { + celix_status_t status = CELIX_SUCCESS; + + *package = calloc(1, sizeof(**package)); + if (!(*package)) { + status = CELIX_ENOMEM; + } else { + (*package)->context = context; + (*package)->manifest = manifest; + (*package)->bundleInfos = NULL; + (*package)->resourceInfos = NULL; + (*package)->nameToBundleInfo = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + (*package)->pathToEntry = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL); + status = arrayList_create(&(*package)->bundleInfos); + if (status == CELIX_SUCCESS) { + status = arrayList_create(&(*package)->resourceInfos); + if (status == CELIX_SUCCESS) { + status = deploymentPackage_processEntries(*package); + if (status == CELIX_SUCCESS) { + int i; + for (i = 0; i < arrayList_size((*package)->bundleInfos); i++) { + bundle_info_pt info = arrayList_get((*package)->bundleInfos, i); + hashMap_put((*package)->nameToBundleInfo, info->symbolicName, info); + } + for (i = 0; i < arrayList_size((*package)->resourceInfos); i++) { + resource_info_pt info = arrayList_get((*package)->resourceInfos, i); + hashMap_put((*package)->pathToEntry, info->path, info); + } + } + } + } + } + + return status; +} + +celix_status_t deploymentPackage_destroy(deployment_package_pt package) { + celix_status_t status = CELIX_SUCCESS; + int i; + + + manifest_destroy(package->manifest); + + hashMap_destroy(package->nameToBundleInfo, false, false); + hashMap_destroy(package->pathToEntry, false, false); + + + for(i = arrayList_size(package->bundleInfos); i > 0; --i) { + free(arrayList_remove(package->bundleInfos, 0)); + } + + arrayList_destroy(package->bundleInfos); + + for (i = arrayList_size(package->resourceInfos); i > 0; --i) { + free(arrayList_remove(package->resourceInfos, 0)); + } + + + arrayList_destroy(package->resourceInfos); + + free(package); + + return status; +} + +celix_status_t deploymentPackage_getName(deployment_package_pt package, const char **name) { + *name = manifest_getValue(package->manifest, "DeploymentPackage-SymbolicName"); + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getBundleInfos(deployment_package_pt package, array_list_pt *infos) { + *infos = arrayList_clone(package->bundleInfos); + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getBundleInfoByName(deployment_package_pt package, const char *name, bundle_info_pt *info) { + *info = hashMap_get(package->nameToBundleInfo, name); + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getBundle(deployment_package_pt package, const char *name, bundle_pt *bundle) { + if (hashMap_containsKey(package->nameToBundleInfo, name)) { + array_list_pt bundles = NULL; + bundleContext_getBundles(package->context, &bundles); + int i; + for (i = 0; i < arrayList_size(bundles); i++) { + bundle_pt ibundle = arrayList_get(bundles, i); + module_pt module = NULL; + bundle_getCurrentModule(ibundle, &module); + const char *bsn = NULL; + module_getSymbolicName(module, &bsn); + if (strcmp(bsn, name) == 0) { + *bundle = ibundle; + break; + } + } + + arrayList_destroy(bundles); + } + + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getResourceInfos(deployment_package_pt package, array_list_pt *infos) { + *infos = arrayList_clone(package->resourceInfos); + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getResourceInfoByPath(deployment_package_pt package, const char *path, resource_info_pt *info) { + *info = hashMap_get(package->pathToEntry, path); + return CELIX_SUCCESS; +} + +celix_status_t deploymentPackage_getVersion(deployment_package_pt package, version_pt *version) { + const char *versionStr = manifest_getValue(package->manifest, "DeploymentPackage-Version"); + return version_createVersionFromString(versionStr, version); +} + +celix_status_t deploymentPackage_processEntries(deployment_package_pt package) { + celix_status_t status = CELIX_SUCCESS; + + hash_map_pt entries = NULL; + manifest_getEntries(package->manifest, &entries); + hash_map_iterator_pt iter = hashMapIterator_create(entries); + while (hashMapIterator_hasNext(iter)) { + hash_map_entry_pt entry = hashMapIterator_nextEntry(iter); + char *name = hashMapEntry_getKey(entry); + properties_pt values = hashMapEntry_getValue(entry); + + bool isBundleResource; + deploymentPackage_isBundleResource(values, &isBundleResource); + if (isBundleResource) { + bundle_info_pt info = calloc(1, sizeof(*info)); + info->path = name; + info->attributes = values; + info->symbolicName = (char*)properties_get(values, OSGI_FRAMEWORK_BUNDLE_SYMBOLICNAME); + const char *version = properties_get(values, OSGI_FRAMEWORK_BUNDLE_VERSION); + info->version = NULL; + status = version_createVersionFromString((char*)version, &info->version); + const char *customizer = properties_get(values, DEPLOYMENTPACKAGE_CUSTOMIZER); + deploymentPackage_parseBooleanHeader((char*)customizer, &info->customizer); + + arrayList_add(package->bundleInfos, info); + } else { + resource_info_pt info = calloc(1, sizeof(*info)); + info->path = name; + info->attributes = values; + info->resourceProcessor = (char*)properties_get(values,RESOURCE_PROCESSOR); + + arrayList_add(package->resourceInfos, info); + } + } + hashMapIterator_destroy(iter); + + return status; +} + +static celix_status_t deploymentPackage_isBundleResource(properties_pt attributes, bool *isBundleResource) { + *isBundleResource = properties_get(attributes, (char *) OSGI_FRAMEWORK_BUNDLE_SYMBOLICNAME) != NULL; + return CELIX_SUCCESS; +} + +static celix_status_t deploymentPackage_parseBooleanHeader(const char *value, bool *boolValue) { + *boolValue = false; + if (value != NULL) { + if (strcmp(value, "true") == 0) { + *boolValue = true; + } else { + *boolValue = false; + } + } + return CELIX_SUCCESS; +} + + http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/deployment_package.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/deployment_package.h b/deployment_admin/src/deployment_package.h new file mode 100644 index 0000000..06c1767 --- /dev/null +++ b/deployment_admin/src/deployment_package.h @@ -0,0 +1,76 @@ +/** + *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. + */ +/* + * deployment_package.h + * + * \date Nov 8, 2011 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef DEPLOYMENT_PACKAGE_H_ +#define DEPLOYMENT_PACKAGE_H_ + +#include "version.h" +#include "bundle_context.h" + +#include "array_list.h" + +struct bundle_info { + char *path; + version_pt version; + char *symbolicName; + bool customizer; + + properties_pt attributes; +}; + +typedef struct bundle_info *bundle_info_pt; + +struct resource_info { + char *path; + properties_pt attributes; + + char *resourceProcessor; +}; + +typedef struct resource_info *resource_info_pt; + +struct deployment_package { + bundle_context_pt context; + manifest_pt manifest; + array_list_pt bundleInfos; + array_list_pt resourceInfos; + hash_map_pt nameToBundleInfo; + hash_map_pt pathToEntry; +}; + +typedef struct deployment_package *deployment_package_pt; + +celix_status_t deploymentPackage_create(bundle_context_pt context, manifest_pt manifest, deployment_package_pt *package); +celix_status_t deploymentPackage_destroy(deployment_package_pt package); +celix_status_t deploymentPackage_getName(deployment_package_pt package, const char** name); +celix_status_t deploymentPackage_getBundleInfos(deployment_package_pt package, array_list_pt *infos); +celix_status_t deploymentPackage_getBundleInfoByName(deployment_package_pt package, const char* name, bundle_info_pt *info); +celix_status_t deploymentPackage_getResourceInfos(deployment_package_pt package, array_list_pt *infos); +celix_status_t deploymentPackage_getResourceInfoByPath(deployment_package_pt package, const char* path, resource_info_pt *info); +celix_status_t deploymentPackage_getBundle(deployment_package_pt package, const char* name, bundle_pt *bundle); +celix_status_t deploymentPackage_getVersion(deployment_package_pt package, version_pt *version); + +#endif /* DEPLOYMENT_PACKAGE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/ioapi.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/ioapi.c b/deployment_admin/src/ioapi.c new file mode 100644 index 0000000..49958f6 --- /dev/null +++ b/deployment_admin/src/ioapi.c @@ -0,0 +1,235 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + +*/ + +#if (defined(_WIN32)) + #define _CRT_SECURE_NO_WARNINGS +#endif + +#include "ioapi.h" + +voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +{ + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); + } +} + +long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); + } +} + +ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +{ + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } +} + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +{ + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; +} + + + +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); + +static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + +static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen64((const char*)filename, mode_fopen); + return file; +} + + +static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + + +static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +{ + ZPOS64_T ret; + ret = ftello64((FILE *)stream); + return ret; +} + +static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + if (fseek((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; +} + +static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + + if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; +} + + +static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +{ + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/ioapi.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/ioapi.h b/deployment_admin/src/ioapi.h new file mode 100644 index 0000000..8309c4c --- /dev/null +++ b/deployment_admin/src/ioapi.h @@ -0,0 +1,200 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications for Zip64 support + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + For more info read MiniZip_info.txt + + Changes + + Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) + Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. + More if/def section may be needed to support other platforms + Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. + (but you should use iowin32.c for windows instead) + +*/ + +#ifndef _ZLIBIOAPI64_H +#define _ZLIBIOAPI64_H + +#if (!defined(_WIN32)) && (!defined(WIN32)) + + // Linux needs this to support file operation on files larger then 4+GB + // But might need better if/def to select just the platforms that needs them. + + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include <stdio.h> +#include <stdlib.h> +#include "zlib.h" + +#if defined(USE_FILE32API) +#define fopen64 fopen +#define ftello64 ftell +#define fseeko64 fseek +#else +#ifdef _MSC_VER + #define fopen64 fopen + #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) + #define ftello64 _ftelli64 + #define fseeko64 _fseeki64 + #else // old MSC + #define ftello64 ftell + #define fseeko64 fseek + #endif +#endif +#endif + +/* +#ifndef ZPOS64_T + #ifdef _WIN32 + #define ZPOS64_T fpos_t + #else + #include <stdint.h> + #define ZPOS64_T uint64_t + #endif +#endif +*/ + +#ifdef HAVE_MINIZIP64_CONF_H +#include "mz64conf.h" +#endif + +/* a type choosen by DEFINE */ +#ifdef HAVE_64BIT_INT_CUSTOM +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +#else +#ifdef HAS_STDINT_H +#include "stdint.h" +typedef uint64_t ZPOS64_T; +#else + + +#if defined(_MSC_VER) || defined(__BORLANDC__) +typedef unsigned __int64 ZPOS64_T; +#else +typedef unsigned long long int ZPOS64_T; +#endif +#endif +#endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) + #define ZCALLBACK CALLBACK + #else + #define ZCALLBACK + #endif +#endif + + + + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + + +/* here is the "old" 32 bits structure structure */ +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + +typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); + +typedef struct zlib_filefunc64_def_s +{ + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc64_def; + +void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +/* now internal definition, only for zip.c and unzip.h */ +typedef struct zlib_filefunc64_32_def_s +{ + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; +} zlib_filefunc64_32_def; + + +#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) +//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) + +voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); +long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); +ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + +#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) +#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) +#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) + +#ifdef __cplusplus +} +#endif + +#endif http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log.c b/deployment_admin/src/log.c new file mode 100644 index 0000000..98e757d --- /dev/null +++ b/deployment_admin/src/log.c @@ -0,0 +1,73 @@ +/** + *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. + */ +/* + * log.c + * + * \date Apr 19, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#include <stddef.h> +#include <stdlib.h> + +#include "celix_errno.h" + +#include "log.h" +#include "log_store.h" + +struct log { + log_store_pt logStore; +}; + +celix_status_t log_create(log_store_pt store, log_pt *log) { + celix_status_t status = CELIX_SUCCESS; + + *log = calloc(1, sizeof(**log)); + if (!*log) { + status = CELIX_ENOMEM; + } else { + (*log)->logStore = store; + } + + return status; +} + +celix_status_t log_destroy(log_pt *log) { + free(*log); + return CELIX_SUCCESS; +} + +celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties) { + celix_status_t status; + + log_event_pt event = NULL; + + status = logStore_put(log->logStore, type, properties, &event); + + return status; +} + +celix_status_t log_bundleChanged(void * listener, bundle_event_pt event) { + return CELIX_SUCCESS; +} + +celix_status_t log_frameworkEvent(void * listener, framework_event_pt event) { + return CELIX_SUCCESS; +} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log.h b/deployment_admin/src/log.h new file mode 100644 index 0000000..fa77911 --- /dev/null +++ b/deployment_admin/src/log.h @@ -0,0 +1,44 @@ +/** + *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. + */ +/* + * log.h + * + * \date Apr 18, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef LOG_H_ +#define LOG_H_ + +#include "log_event.h" +#include "log_store.h" + +#include "bundle_event.h" +#include "framework_event.h" + +typedef struct log *log_pt; + +celix_status_t log_create(log_store_pt store, log_pt *log); +celix_status_t log_log(log_pt log, unsigned int type, properties_pt properties); + +celix_status_t log_bundleChanged(void * listener, bundle_event_pt event); +celix_status_t log_frameworkEvent(void * listener, framework_event_pt event); + +#endif /* LOG_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log_event.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log_event.h b/deployment_admin/src/log_event.h new file mode 100644 index 0000000..c1a76a9 --- /dev/null +++ b/deployment_admin/src/log_event.h @@ -0,0 +1,43 @@ +/** + *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. + */ +/* + * log_event.h + * + * \date Apr 19, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef LOG_EVENT_H_ +#define LOG_EVENT_H_ + +#include "properties.h" + +struct log_event { + char *targetId; + unsigned long logId; + unsigned long id; + unsigned long time; + unsigned int type; + properties_pt properties; +}; + +typedef struct log_event *log_event_pt; + +#endif /* LOG_EVENT_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log_store.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log_store.c b/deployment_admin/src/log_store.c new file mode 100644 index 0000000..c2bfabc --- /dev/null +++ b/deployment_admin/src/log_store.c @@ -0,0 +1,94 @@ +/** + *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. + */ +/* + * log_store.c + * + * \date Apr 18, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ +#include <stdlib.h> + +#include <time.h> + +#include "celix_errno.h" +#include "array_list.h" + +#include "log_store.h" +#include "log.h" + +struct log_store { + unsigned long storeId; + + array_list_pt logEvents; +}; + +static celix_status_t logStore_getNextID(log_store_pt store, unsigned long *id); + +celix_status_t logStore_create(log_store_pt *store) { + celix_status_t status = CELIX_SUCCESS; + *store = calloc(1, sizeof(**store)); + if (!*store) { + status = CELIX_ENOMEM; + } else { + (*store)->storeId = 1; + arrayList_create(&(*store)->logEvents); + } + + return status; +} + +celix_status_t logStore_put(log_store_pt store, unsigned int type, properties_pt properties, log_event_pt *event) { + celix_status_t status = CELIX_SUCCESS; + + *event = calloc(1, sizeof(**event)); + (*event)->targetId = NULL; + (*event)->logId = store->storeId; + (*event)->id = 0; + (*event)->time = time(NULL); + (*event)->type = type; + (*event)->properties = properties; + + logStore_getNextID(store, &(*event)->id); + + arrayList_add(store->logEvents, *event); + + return status; +} + +celix_status_t logStore_getLogId(log_store_pt store, unsigned long *id) { + *id = store->storeId; + return CELIX_SUCCESS; +} + +celix_status_t logStore_getEvents(log_store_pt store, array_list_pt *events) { + *events = store->logEvents; + return CELIX_SUCCESS; +} + +celix_status_t logStore_getHighestId(log_store_pt store, long *id) { + *id = ((long) arrayList_size(store->logEvents)) - 1; + return CELIX_SUCCESS; +} + +static celix_status_t logStore_getNextID(log_store_pt store, unsigned long *id) { + *id = arrayList_size(store->logEvents); + return CELIX_SUCCESS; +} + http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log_store.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log_store.h b/deployment_admin/src/log_store.h new file mode 100644 index 0000000..84299b3 --- /dev/null +++ b/deployment_admin/src/log_store.h @@ -0,0 +1,45 @@ +/** + *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. + */ +/* + * log_store.h + * + * \date Apr 18, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef LOG_STORE_H_ +#define LOG_STORE_H_ + +#include "log_event.h" + +#include "properties.h" +#include "array_list.h" + +typedef struct log_store *log_store_pt; + +celix_status_t logStore_create(log_store_pt *store); +celix_status_t logStore_put(log_store_pt store, unsigned int type, properties_pt properties, log_event_pt *event); + +celix_status_t logStore_getLogId(log_store_pt store, unsigned long *id); +celix_status_t logStore_getEvents(log_store_pt store, array_list_pt *events); + +celix_status_t logStore_getHighestId(log_store_pt store, long *id); + +#endif /* LOG_STORE_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log_sync.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log_sync.c b/deployment_admin/src/log_sync.c new file mode 100644 index 0000000..242beea --- /dev/null +++ b/deployment_admin/src/log_sync.c @@ -0,0 +1,209 @@ +/** + *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. + */ +/* + * log_sync.c + * + * \date Apr 19, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <curl/curl.h> +#include <curl/easy.h> + +#include "celix_errno.h" +#include "celix_log.h" +#include "celixbool.h" + +#include "celix_threads.h" + +#include "log_sync.h" +#include "log_event.h" + +struct log_sync { + log_store_pt logStore; + + char *targetId; + bool running; + + celix_thread_t syncTask; +}; + +struct log_descriptor { + char *targetId; + unsigned long logId; + unsigned long low; + unsigned long high; +}; + +typedef struct log_descriptor *log_descriptor_pt; + +celix_status_t logSync_queryLog(log_sync_pt logSync, char *targetId, long logId, char **queryReply); +static size_t logSync_readQeury(void *contents, size_t size, size_t nmemb, void *userp); +static void *logSync_synchronize(void *logSyncP); + +celix_status_t logSync_create(char *targetId, log_store_pt store, log_sync_pt *logSync) { + celix_status_t status = CELIX_SUCCESS; + + *logSync = calloc(1, sizeof(**logSync)); + if (!*logSync) { + status = CELIX_ENOMEM; + } else { + (*logSync)->logStore = store; + (*logSync)->targetId = targetId; + (*logSync)->syncTask = celix_thread_default; + (*logSync)->running = true; + + celixThread_create(&(*logSync)->syncTask, NULL, logSync_synchronize, *logSync); + } + + return status; +} + +celix_status_t logSync_parseLogDescriptor(log_sync_pt logSync, char *descriptorString, log_descriptor_pt *descriptor) { + celix_status_t status = CELIX_SUCCESS; + + fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Descriptor: %s", descriptorString); + char *last = NULL; + char *targetId = strtok_r(descriptorString, ",", &last); + char *logIdStr = strtok_r(NULL, ",", &last); + long logId = 0; + if (logIdStr != NULL) { + logId = atol(logIdStr); + } + char *range = strtok_r(NULL, ",", &last); + fw_log(logger, OSGI_FRAMEWORK_LOG_DEBUG, "Range: %s", range); + + long low = 0; + long high = 0; + if (range != NULL) { + char *rangeToken = NULL; + low = atol(strtok_r(range, "-", &rangeToken)); + high = atol(strtok_r(NULL, "-", &rangeToken)); + } + + *descriptor = calloc(1, sizeof(**descriptor)); + if (!*descriptor) { + status = CELIX_ENOMEM; + } else { + (*descriptor)->targetId = targetId; + (*descriptor)->logId = logId; + (*descriptor)->low = low; + (*descriptor)->high = high; + } + + return status; +} + +static void *logSync_synchronize(void *logSyncP) { + log_sync_pt logSync = logSyncP; + + while (logSync->running) { + + //query current log + // http://localhost:8080/auditlog/query?tid=targetid&logid=logid + char *logDescriptorString = NULL; + unsigned long id = 0; + logStore_getLogId(logSync->logStore, &id); + logSync_queryLog(logSync, logSync->targetId, id, &logDescriptorString); + log_descriptor_pt descriptor = NULL; + logSync_parseLogDescriptor(logSync, logDescriptorString, &descriptor); + + long highest = 0; + logStore_getHighestId(logSync->logStore, &highest); + + if (highest >= 0) { + int i; + for (i = descriptor->high + 1; i <= highest; i++) { + array_list_pt events = NULL; + logStore_getEvents(logSync->logStore, &events); + } + } + + if(descriptor!=NULL){ + free(descriptor); + } + + sleep(10); + } + + + celixThread_exit(NULL); + return NULL; +} + +struct MemoryStruct { + char *memory; + size_t size; +}; + +celix_status_t logSync_queryLog(log_sync_pt logSync, char *targetId, long logId, char **queryReply) { + // http://localhost:8080/auditlog/query?tid=targetid&logid=logid + celix_status_t status = CELIX_SUCCESS; + int length = strlen(targetId) + 60; + char query[length]; + snprintf(query, length, "http://localhost:8080/auditlog/query?tid=%s&logid=1", targetId); + + CURL *curl; + CURLcode res; + curl = curl_easy_init(); + struct MemoryStruct chunk; + chunk.memory = calloc(1, sizeof(char)); + chunk.size = 0; + if (curl) { + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); + curl_easy_setopt(curl, CURLOPT_URL, query); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, logSync_readQeury); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk); + curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); + res = curl_easy_perform(curl); + if (res != CURLE_OK) { + status = CELIX_BUNDLE_EXCEPTION; + } + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "Error: %d", res); + /* always cleanup */ + curl_easy_cleanup(curl); + + *queryReply = strdup(chunk.memory); + } + + return status; +} + +static size_t logSync_readQeury(void *contents, size_t size, size_t nmemb, void *userp) { + size_t realsize = size * nmemb; + struct MemoryStruct *mem = (struct MemoryStruct *)userp; + + mem->memory = realloc(mem->memory, mem->size + realsize + 1); + if (mem->memory == NULL) { + /* out of memory! */ + fw_log(logger, OSGI_FRAMEWORK_LOG_ERROR, "not enough memory (realloc returned NULL)"); + exit(EXIT_FAILURE); + } + + memcpy(&(mem->memory[mem->size]), contents, realsize); + mem->size += realsize; + mem->memory[mem->size] = 0; + + return realsize; +} http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/log_sync.h ---------------------------------------------------------------------- diff --git a/deployment_admin/src/log_sync.h b/deployment_admin/src/log_sync.h new file mode 100644 index 0000000..7cd10d9 --- /dev/null +++ b/deployment_admin/src/log_sync.h @@ -0,0 +1,36 @@ +/** + *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. + */ +/* + * log_sync.h + * + * \date Apr 19, 2012 + * \author <a href="mailto:[email protected]">Apache Celix Project Team</a> + * \copyright Apache License, Version 2.0 + */ + +#ifndef LOG_SYNC_H_ +#define LOG_SYNC_H_ + +#include "log_store.h" + +typedef struct log_sync *log_sync_pt; + +celix_status_t logSync_create(char *targetId, log_store_pt store, log_sync_pt *logSync); + +#endif /* LOG_SYNC_H_ */ http://git-wip-us.apache.org/repos/asf/celix/blob/a1c30887/deployment_admin/src/miniunz.c ---------------------------------------------------------------------- diff --git a/deployment_admin/src/miniunz.c b/deployment_admin/src/miniunz.c new file mode 100644 index 0000000..e543c3b --- /dev/null +++ b/deployment_admin/src/miniunz.c @@ -0,0 +1,402 @@ +/** License + * ---------------------------------------------------------- + * Condition of use and distribution are the same than zlib : + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * ---------------------------------------------------------- + */ +/* + miniunz.c + Version 1.1, February 14h, 2010 + sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) + + Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) + + Modifications of Unzip for Zip64 + Copyright (C) 2007-2008 Even Rouault + + Modifications for Zip64 support on both zip and unzip + Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) + + Changes made to the original source specific for Apache Celix: + * Updated several parts to use output directory fitting Celix. + * Removed several parts not needed (main function etc). + * Added some checks for OSX/Apple +*/ + +#ifndef _WIN32 + #ifndef __USE_FILE_OFFSET64 + #define __USE_FILE_OFFSET64 + #endif + #ifndef __USE_LARGEFILE64 + #define __USE_LARGEFILE64 + #endif + #ifndef _LARGEFILE64_SOURCE + #define _LARGEFILE64_SOURCE + #endif + #ifndef _FILE_OFFSET_BIT + #define _FILE_OFFSET_BIT 64 + #endif +#endif + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <fcntl.h> + +#include <unistd.h> +#include <utime.h> +#include <sys/stat.h> + +#include "unzip.h" +#include "archive.h" + +#define CASESENSITIVITY (0) +#define WRITEBUFFERSIZE (8192) +#define MAXFILENAME (256) + +#ifdef _WIN32 +#define USEWIN32IOAPI +#include "iowin32.h" +#endif +/* + mini unzip, demo of unzip package + + usage : + Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir] + + list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT + if it exists +*/ + + +/* change_file_date : change the date/time of a file + filename : the filename of the file where date/time must be modified + dosdate : the new date at the MSDos format (4 bytes) + tmu_date : the SAME new date at the tm_unz format */ +void change_file_date(filename,dosdate,tmu_date) + const char *filename; + uLong dosdate; + tm_unz tmu_date; +{ +#ifdef _WIN32 + HANDLE hFile; + FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite; + + hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE, + 0,NULL,OPEN_EXISTING,0,NULL); + GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite); + DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal); + LocalFileTimeToFileTime(&ftLocal,&ftm); + SetFileTime(hFile,&ftm,&ftLastAcc,&ftm); + CloseHandle(hFile); +#else +#if defined(unix) || defined(__APPLE__) + struct utimbuf ut; + struct tm newdate; + newdate.tm_sec = tmu_date.tm_sec; + newdate.tm_min=tmu_date.tm_min; + newdate.tm_hour=tmu_date.tm_hour; + newdate.tm_mday=tmu_date.tm_mday; + newdate.tm_mon=tmu_date.tm_mon; + if (tmu_date.tm_year > 1900) + newdate.tm_year=tmu_date.tm_year - 1900; + else + newdate.tm_year=tmu_date.tm_year ; + newdate.tm_isdst=-1; + + ut.actime=ut.modtime=mktime(&newdate); + utime(filename,&ut); +#endif +#endif +} + + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#ifdef _WIN32 + ret = _mkdir(dirname); +#else +#if defined unix || defined __APPLE__ + ret = mkdir(dirname,0775); +#endif +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = (int)strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + if (buffer==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} + +int do_extract_currentfile(unzFile uf, char * revisionRoot) { + char filename_inzip[256]; + char* filename_withoutpath; + char* p; + int err=UNZ_OK; + FILE *fout=NULL; + void* buf; + uInt size_buf; + + unz_file_info64 file_info; + err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); + + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); + return err; + } + + size_buf = WRITEBUFFERSIZE; + buf = (void*)malloc(size_buf); + if (buf==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + + p = filename_withoutpath = filename_inzip; + while ((*p) != '\0') + { + if (((*p)=='/') || ((*p)=='\\')) + filename_withoutpath = p+1; + p++; + } + + if ((*filename_withoutpath)=='\0') { + char dir[strlen(revisionRoot) + strlen(filename_inzip) + 2]; + strcpy(dir, revisionRoot); + strcat(dir, "/"); + strcat(dir, filename_inzip); + mymkdir(dir); + } + else + { + const char* write_filename; + int skip=0; + write_filename = filename_inzip; + + int length = strlen(write_filename) + strlen(revisionRoot) + 2; + char fWFN[length]; + strcpy(fWFN, revisionRoot); + strcat(fWFN, "/"); + strcat(fWFN, write_filename); + + err = unzOpenCurrentFile(uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err); + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=fopen64(fWFN,"wb"); + + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + int length = strlen(write_filename) + strlen(revisionRoot) + 2; + char dir[length]; + strcpy(dir, revisionRoot); + strcat(dir, "/"); + strcat(dir, write_filename); + makedir(dir); + *(filename_withoutpath-1)=c; + + fout=fopen64(fWFN,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + if (fout) + fclose(fout); + + if (err==0) + change_file_date(fWFN,file_info.dosDate, + file_info.tmu_date); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int do_extract(unzFile uf, char * revisionRoot) { + uLong i; + unz_global_info64 gi; + int err; + + err = unzGetGlobalInfo64(uf,&gi); + if (err!=UNZ_OK) + printf("error %d with zipfile in unzGetGlobalInfo \n",err); + + for (i=0;i<gi.number_entry;i++) + { + if (do_extract_currentfile(uf, revisionRoot) != UNZ_OK) + break; + + if ((i+1)<gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzGoToNextFile\n",err); + break; + } + } + } + + return 0; +} + +celix_status_t unzip_extractDeploymentPackage(char * packageName, char * destination) { + celix_status_t status = CELIX_SUCCESS; + char filename_try[MAXFILENAME+16] = ""; + unzFile uf=NULL; + + if (packageName!=NULL) + { + +# ifdef USEWIN32IOAPI + zlib_filefunc64_def ffunc; +# endif + + strncpy(filename_try, packageName,MAXFILENAME-1); + /* strncpy doesnt append the trailing NULL, of the string is too long. */ + filename_try[ MAXFILENAME ] = '\0'; + +# ifdef USEWIN32IOAPI + fill_win32_filefunc64A(&ffunc); + uf = unzOpen2_64(bundleName,&ffunc); +# else + uf = unzOpen64(packageName); +# endif + if (uf==NULL) + { + strcat(filename_try,".zip"); +# ifdef USEWIN32IOAPI + uf = unzOpen2_64(filename_try,&ffunc); +# else + uf = unzOpen64(filename_try); +# endif + } + } + + if (uf==NULL) + { + printf("Cannot open %s or %s.zip\n",packageName,packageName); + status = CELIX_FILE_IO_EXCEPTION; + } else { + if (do_extract(uf, destination) != 0) { + status = CELIX_FILE_IO_EXCEPTION; + } + + unzClose(uf); + } + + return status; +}
