From e7ef07f5798775437910b36cfe304b46700ae734 Mon Sep 17 00:00:00 2001 From: Priyansh61 <21bec080@iiitdmj.ac.in> Date: Sat, 19 Aug 2023 00:14:17 +0530 Subject: [PATCH 1/3] Added zssServer to the AppStore Signed-off-by: Priyansh61 <21bec080@iiitdmj.ac.in> --- .../app-store/zssServer/build/build.sh | 36 +++ .../app-store/zssServer/build/pluginAPI.x | 144 +++++++++++ .../zssServer/c/appStoreDataService.c | 226 ++++++++++++++++++ 3 files changed, 406 insertions(+) create mode 100644 system-apps/app-store/zssServer/build/build.sh create mode 100644 system-apps/app-store/zssServer/build/pluginAPI.x create mode 100644 system-apps/app-store/zssServer/c/appStoreDataService.c diff --git a/system-apps/app-store/zssServer/build/build.sh b/system-apps/app-store/zssServer/build/build.sh new file mode 100644 index 00000000..ed628b9b --- /dev/null +++ b/system-apps/app-store/zssServer/build/build.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# © 2022-2024 Rocket Software, Inc. or its affiliates. All Rights Reserved. +# ROCKET SOFTWARE, INC. CONFIDENTIAL + +mkdir tmp 2>/dev/null +cd tmp + +if [ -z "$ZSS_DIR" ] +then + echo "Set ZSS_DIR env var to build" + exit 1 +fi + + +ZOWECOMMON=${ZSS_DIR}/deps/zowe-common-c + +mkdir ../../../lib 2>/dev/null + +xlc \ + -D_OPEN_THREADS \ + -D_XOPEN_SOURCE=600 \ + -DAPF_AUTHORIZED=0 \ + -DNOIBMHTTP \ + "-Wa,goff" "-Wc,langlvl(EXTC99),float(HEX),agg,expo,list(),so(),search(),\ + goff,xref,gonum,roconst,gonum,asm,asmlib('SYS1.MACLIB'),asmlib('CEE.SCEEMAC'),dll" -Wl,dll \ + -I ${ZSS_DIR}/h -I ${ZOWECOMMON}/h \ + -I ${ZOWECOMMON}/platform/posix \ + -o ../../../lib/appStoreDataService.so \ + ../../c/appStoreDataService.c \ + ../pluginAPI.x \ + +echo "Compile finished with rc=$?" + +extattr +p ../../../lib/appStoreDataService.so + + diff --git a/system-apps/app-store/zssServer/build/pluginAPI.x b/system-apps/app-store/zssServer/build/pluginAPI.x new file mode 100644 index 00000000..13fb800b --- /dev/null +++ b/system-apps/app-store/zssServer/build/pluginAPI.x @@ -0,0 +1,144 @@ + IMPORT CODE,'zssServer','makeHttpDataService' + IMPORT CODE,'zssServer','makeWebSocketService' + IMPORT CODE,'zssServer','makeWSEndpoint' + IMPORT CODE,'zssServer','makeWSMessageHandler' + IMPORT CODE,'zssServer','zowelog' + IMPORT CODE,'zssServer','zowedump' + IMPORT CODE,'zssServer','dumpbuffer' + IMPORT CODE,'zssServer','recoveryPush' + IMPORT CODE,'zssServer','recoveryPop' + IMPORT CODE,'zssServer','convertCharset' + IMPORT CODE,'zssServer','firstStringListElt' + IMPORT CODE,'zssServer','makeStringList' + IMPORT CODE,'zssServer','addToStringList' + IMPORT CODE,'zssServer','stringListPrint' + IMPORT CODE,'zssServer','stringListLength' + IMPORT CODE,'zssServer','stringListContains' + IMPORT CODE,'zssServer','stringListLast' + IMPORT CODE,'zssServer','addToStringListUnique' + IMPORT CODE,'zssServer','stringConcatenate' + IMPORT CODE,'zssServer','nullTerminate' + IMPORT CODE,'zssServer','indexOf' + IMPORT CODE,'zssServer','lastIndexOf' + IMPORT CODE,'zssServer','indexOfString' + IMPORT CODE,'zssServer','safeMalloc' + IMPORT CODE,'zssServer','safeMalloc31' + IMPORT CODE,'zssServer','safeMalloc64' + IMPORT CODE,'zssServer','safeFree' + IMPORT CODE,'zssServer','safeFree31' + IMPORT CODE,'zssServer','safeFree64' + IMPORT CODE,'zssServer','htCreate' + IMPORT CODE,'zssServer','fileInfo' + IMPORT CODE,'zssServer','fileInfoIsDirectory' + IMPORT CODE,'zssServer','fileDelete' + IMPORT CODE,'zssServer','htDestroy' + IMPORT CODE,'zssServer','htPut' + IMPORT CODE,'zssServer','htGet' + IMPORT CODE,'zssServer','htMap' + IMPORT CODE,'zssServer','makeQueue' + IMPORT CODE,'zssServer','destroyQueue' + IMPORT CODE,'zssServer','qRemove' + IMPORT CODE,'zssServer','qInsert' + IMPORT CODE,'zssServer','makeShortLivedHeap' + IMPORT CODE,'zssServer','makeShortLivedHeap64' + IMPORT CODE,'zssServer','stringHash' + IMPORT CODE,'zssServer','stringCompare' + IMPORT CODE,'zssServer','SLHAlloc' + IMPORT CODE,'zssServer','SLHFree' + IMPORT CODE,'zssServer','setDefaultJSONRESTHeaders' + IMPORT CODE,'zssServer','respondWithJsonError' + IMPORT CODE,'zssServer','respondWithError' + IMPORT CODE,'zssServer','makeCustomJsonPrinter' + IMPORT CODE,'zssServer','makeJsonPrinter' + IMPORT CODE,'zssServer','freeJsonPrinter' + IMPORT CODE,'zssServer','jsonPrintObject' + IMPORT CODE,'zssServer','respondWithJsonPrinter' + IMPORT CODE,'zssServer','setResponseStatus' + IMPORT CODE,'zssServer','setContentType' + IMPORT CODE,'zssServer','addStringHeader' + IMPORT CODE,'zssServer','addIntHeader' + IMPORT CODE,'zssServer','addHeader' + IMPORT CODE,'zssServer','writeHeader' + IMPORT CODE,'zssServer','getHeader' + IMPORT CODE,'zssServer','getQueryParam' + IMPORT CODE,'zssServer','getCheckedParam' + IMPORT CODE,'zssServer','makeIntParamSpec' + IMPORT CODE,'zssServer','makeInt64ParamSpec' + IMPORT CODE,'zssServer','makeStringParamSpec' + IMPORT CODE,'zssServer','jsonStart' + IMPORT CODE,'zssServer','jsonAddString' + IMPORT CODE,'zssServer','jsonAddUnterminatedString' + IMPORT CODE,'zssServer','jsonAddLimitedString' + IMPORT CODE,'zssServer','jsonAddInt' + IMPORT CODE,'zssServer','jsonAddUInt' + IMPORT CODE,'zssServer','jsonAddInt64' + IMPORT CODE,'zssServer','jsonAddBoolean' + IMPORT CODE,'zssServer','jsonEnd' + IMPORT CODE,'zssServer','jsonStartObject' + IMPORT CODE,'zssServer','jsonEndObject' + IMPORT CODE,'zssServer','jsonStartArray' + IMPORT CODE,'zssServer','jsonEndArray' + IMPORT CODE,'zssServer','jsonEnablePrettyPrint' + IMPORT CODE,'zssServer','jsonStartMultipartString' + IMPORT CODE,'zssServer','jsonAppendStringPart' + IMPORT CODE,'zssServer','jsonEndMultipartString' + IMPORT CODE,'zssServer','finishResponse' + IMPORT CODE,'zssServer','jsonObjectGetFirstProperty' + IMPORT CODE,'zssServer','jsonObjectGetNextProperty' + IMPORT CODE,'zssServer','jsonPropertyGetValue' + IMPORT CODE,'zssServer','jsonPropertyGetKey' + IMPORT CODE,'zssServer','jsonObjectGetPropertyValue' + IMPORT CODE,'zssServer','jsonObjectHasKey' + IMPORT CODE,'zssServer','jsonObjectGetNumber' + IMPORT CODE,'zssServer','jsonObjectGetString' + IMPORT CODE,'zssServer','jsonObjectGetObject' + IMPORT CODE,'zssServer','jsonObjectGetBoolean' + IMPORT CODE,'zssServer','jsonObjectGetArray' + IMPORT CODE,'zssServer','jsonArrayGetCount' + IMPORT CODE,'zssServer','jsonArrayGetItem' + IMPORT CODE,'zssServer','jsonArrayGetArray' + IMPORT CODE,'zssServer','jsonArrayGetBoolean' + IMPORT CODE,'zssServer','jsonArrayGetNumber' + IMPORT CODE,'zssServer','jsonArrayGetObject' + IMPORT CODE,'zssServer','jsonArrayGetString' + IMPORT CODE,'zssServer','jsonVerifyHomogeneity' + IMPORT CODE,'zssServer','jsonArrayContainsString' + IMPORT CODE,'zssServer','jsonAsBoolean' + IMPORT CODE,'zssServer','jsonAsNumber' + IMPORT CODE,'zssServer','jsonAsString' + IMPORT CODE,'zssServer','jsonAsArray' + IMPORT CODE,'zssServer','jsonAsObject' + IMPORT CODE,'zssServer','jsonIsArray' + IMPORT CODE,'zssServer','jsonIsBoolean' + IMPORT CODE,'zssServer','jsonIsNull' + IMPORT CODE,'zssServer','jsonIsNumber' + IMPORT CODE,'zssServer','jsonIsObject' + IMPORT CODE,'zssServer','jsonIsString' + IMPORT CODE,'zssServer','jsonObjectProperty' + IMPORT CODE,'zssServer','jsonArrayProperty' + IMPORT CODE,'zssServer','jsonIntProperty' + IMPORT CODE,'zssServer','jsonStringProperty' + IMPORT CODE,'zssServer','jsonPrint' + IMPORT CODE,'zssServer','jsonPrintArray' + IMPORT CODE,'zssServer','jsonPrintObject' + IMPORT CODE,'zssServer','jsonPrintProperty' + IMPORT CODE,'zssServer','reportJSONDataProblem' + IMPORT CODE,'zssServer','jsonParseFile' + IMPORT CODE,'zssServer','jsonParseUnterminatedString' + IMPORT CODE,'zssServer','jsonParseString' + IMPORT CODE,'zssServer','copyStringToNative' + IMPORT CODE,'zssServer','makeXmlPrinter' + IMPORT CODE,'zssServer','makeCustomXmlPrinter' + IMPORT CODE,'zssServer','xmlClose' + IMPORT CODE,'zssServer','xmlStart' + IMPORT CODE,'zssServer','xmlEnd' + IMPORT CODE,'zssServer','xmlAddString' + IMPORT CODE,'zssServer','xmlAddTextElement' + IMPORT CODE,'zssServer','xmlAddCData' + IMPORT CODE,'zssServer','xmlAddBooleanElement' + IMPORT CODE,'zssServer','xmlAddIntElement' + IMPORT CODE,'zssServer','xmlPrintInt' + IMPORT CODE,'zssServer','xmlPrintBoolean' + IMPORT CODE,'zssServer','xmlPrint' + IMPORT CODE,'zssServer','xmlPrintln' + IMPORT CODE,'zssServer','xmlPrintPartial' diff --git a/system-apps/app-store/zssServer/c/appStoreDataService.c b/system-apps/app-store/zssServer/c/appStoreDataService.c new file mode 100644 index 00000000..3139c2c5 --- /dev/null +++ b/system-apps/app-store/zssServer/c/appStoreDataService.c @@ -0,0 +1,226 @@ + +/* + This program and the accompanying materials are + made available under the terms of the Eclipse Public License v2.0 which accompanies + this distribution, and is available at https://www.eclipse.org/legal/epl-v20.html + + SPDX-License-Identifier: EPL-2.0 + + Copyright Contributors to the Zowe Project. +*/ + +#ifdef METTLE +#include +#include +#include +#include +#include +#include +#include "metalio.h" +#include "qsam.h" +#else +#include +#include +#include +#include +#include +#endif + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "charsets.h" +#include "bpxnet.h" +#include "socketmgmt.h" +#include "httpserver.h" +#include "json.h" +#include "logging.h" +#include "dataservice.h" +#include "http.h" + +typedef struct AppStoreServiceData_t +{ + int timesVisited; + uint64 loggingId; +} AppStoreServiceData; + +static int appStoreDataService(HttpService *service, HttpResponse *response) +{ + HttpRequest *request = response->request; + // basically this data is constant throught the whole service irrespective of the request + AppStoreServiceData *serviceData = service->userPointer; + + serviceData->timesVisited++; + + zowelog(NULL, serviceData->loggingId, ZOWE_LOG_WARNING, + "Inside appStoreDataService\n"); + + if (!strcmp(request->method, methodGET)) + { + // Checks for the GET method + jsonPrinter *p = respondWithJsonPrinter(response); + + setResponseStatus(response, 200, "OK"); + setDefaultJSONRESTHeaders(response); + writeHeader(response); + + jsonStart(p); + { + jsonAddString(p, "message", "Get Method for AppStoreDataService"); + } + jsonEnd(p); + } + else if (!strcmp(request->method, methodPOST)) + { + // Checks for the POST method + + // Get the body of the request + char *inPtr = request->contentBody; + + // Convert the header for mainframe + char *nativeBody = copyStringToNative(request->slh, inPtr, strlen(inPtr)); + int inLen = strlen(nativeBody); + char *errBuf[1024]; + + // Checks for the validity of the body if the body is not valid then it will return NULL + Json *body = jsonParseUnterminatedString( + request->slh, nativeBody, inLen, errBuf, sizeof(errBuf)); + + // returns the json object + JsonObject *inputObject = jsonAsObject(body); + + if (inputObject == NULL) + { + respondWithJsonError(response, "Response body has no JSON object", 400, "Bad Request"); + return 0; + } + + // Get the attributes from the json object + Json *nameJson = jsonObjectGetPropertyValue(inputObject, "name"); + Json *autoEncodingJson = jsonObjectGetPropertyValue(inputObject, "auto-encoding"); + + // We will be using this once the installs fails while installing the support module, + // This will serve as kind of force command default we will keep it false only + Json *skipEnableJson = jsonObjectGetPropertyValue(inputObject, "skip-enable"); + Json *registryJson = jsonObjectGetPropertyValue(inputObject, "registry"); + Json *handlerJson = jsonObjectGetPropertyValue(inputObject, "handler"); + + char *autoEncoding = NULL; + bool skipEnable = false; + + if (nameJson == NULL) + { + respondWithJsonError(response, "Missing name property from Json Body", 400, "Bad Request"); + return 0; + } + + if (autoEncodingJson != NULL) + { + autoEncoding = jsonAsBoolean(autoEncodingJson); + } + else + { + // keep the default encoding auto + char encoding[5]; + strcpy(encoding, "auto"); + autoEncoding = encoding; + } + + if (skipEnableJson != NULL) + { + skipEnable = jsonAsBoolean(skipEnableJson); + } + + if (registryJson == NULL) + { + respondWithJsonError(response, "Missing registry property from Json Body", 400, "Bad Request"); + return 0; + } + + if (handlerJson == NULL) + { + respondWithJsonError(response, "Missing handler property from Json Body", 400, "Bad Request"); + return 0; + } + + // Convert the json object to string + char *name = jsonAsString(nameJson); + char *registry = jsonAsString(registryJson); + char *handler = jsonAsString(handlerJson); + + char cmd[10280]; + + int bufferPos = 0; + + bufferPos += sprintf(cmd + bufferPos, "zwe components install "); + + // Add the component name + bufferPos += sprintf(cmd + bufferPos, "--component %s ", name); + + // Add the registry + bufferPos += sprintf(cmd + bufferPos, "--registry %s ", registry); + + // Add the handler + bufferPos += sprintf(cmd + bufferPos, "--handler %s", handler); + + zowelog(NULL, serviceData->loggingId, ZOWE_LOG_DEBUG, + "Executing '%s'\n",cmd); + + int retCode = system(cmd); + + zowelog(NULL, serviceData->loggingId, retCode ? ZOWE_LOG_WARNING : ZOWE_LOG_DEBUG, + "App Store call '%s' ended in rc=%d\n", cmd, retCode); + + if (!retCode) { + jsonPrinter *p = writeSuccess(response, retCode, "string"); + jsonAddInt(p, "rc", retCode); + + jsonEnd(p); + } else { + jsonPrinter *p = respondWithJsonPrinter(response); + setResponseStatus(response, 500, "Internal Server Error"); + setDefaultJSONRESTHeaders(response); + writeHeader(response); + + jsonStart(p); + jsonAddString(p, "error", "Command failed to execute.\n"); + jsonEnd(p); + } + } else { + jsonPrinter *p = respondWithJsonPrinter(response); + + setResponseStatus(response, 405, "Method Not Allowed"); + setDefaultJSONRESTHeaders(response); + addStringHeader(response, "Allow", "GET, POST"); + writeHeader(response); + + jsonStart(p); + { + jsonAddString(p, "error", "Only POST requests are supported"); + } + jsonEnd(p); + } + + finishResponse(response); + + return 0; + + +} + +void appStoreDataServiceInstaller(DataService *dataService, HttpServer *server) +{ + int returnCode = 0; + int reasonCode = 0; + + HttpService *httpService = makeHttpDataService(dataService, server); + httpService->authType = SERVICE_AUTH_NATIVE_WITH_SESSION_TOKEN; + httpService->serviceFunction = appStoreDataService; + httpService->runInSubtask = TRUE; + httpService->doImpersonation = TRUE; + + AppStoreServiceData *serviceData = (AppStoreServiceData *)safeMalloc(sizeof(AppStoreServiceData), "AppStoreServiceData"); + serviceData->loggingId = dataService->loggingIdentifier; + + httpService->userPointer = serviceData; +} \ No newline at end of file From 3bf800cbe6b457c732852e4d29698c5efcdb686f Mon Sep 17 00:00:00 2001 From: Priyansh61 <21bec080@iiitdmj.ac.in> Date: Wed, 6 Sep 2023 16:07:37 +0530 Subject: [PATCH 2/3] Fixed the type error bugs Signed-off-by: Priyansh61 <21bec080@iiitdmj.ac.in> --- .../zssServer/c/appStoreDataService.c | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/system-apps/app-store/zssServer/c/appStoreDataService.c b/system-apps/app-store/zssServer/c/appStoreDataService.c index 3139c2c5..1686bded 100644 --- a/system-apps/app-store/zssServer/c/appStoreDataService.c +++ b/system-apps/app-store/zssServer/c/appStoreDataService.c @@ -44,6 +44,30 @@ typedef struct AppStoreServiceData_t uint64 loggingId; } AppStoreServiceData; +static jsonPrinter *writeSuccess(HttpResponse *response, int rc, char *type) { + int convert = TRUE; + int outCCSID = CCSID_EBCDIC_1047; + int reasonCode = 0; + int translationLength = 0; + char *convertBuffer = safeMalloc(4096, "ConvertBuffer"); + + if (!strcmp(type, "tar") || !strcmp(type, "pax")){ + convert = FALSE; + } + + jsonPrinter *p = respondWithJsonPrinter(response); + + setResponseStatus(response, 200, "OK"); + setDefaultJSONRESTHeaders(response); + writeHeader(response); + + jsonStart(p); + jsonStartMultipartString(p, "output"); + jsonEndMultipartString(p); + safeFree(convertBuffer, 4096); + return p; +} + static int appStoreDataService(HttpService *service, HttpResponse *response) { HttpRequest *request = response->request; @@ -80,7 +104,7 @@ static int appStoreDataService(HttpService *service, HttpResponse *response) // Convert the header for mainframe char *nativeBody = copyStringToNative(request->slh, inPtr, strlen(inPtr)); int inLen = strlen(nativeBody); - char *errBuf[1024]; + char errBuf[1024]; // Checks for the validity of the body if the body is not valid then it will return NULL Json *body = jsonParseUnterminatedString( @@ -116,7 +140,15 @@ static int appStoreDataService(HttpService *service, HttpResponse *response) if (autoEncodingJson != NULL) { - autoEncoding = jsonAsBoolean(autoEncodingJson); + if (jsonAsBoolean(autoEncodingJson)) { + char encoding[5]; + strcpy(encoding, "yes"); + autoEncoding = encoding; + } else { + char encoding[5]; + strcpy(encoding, "no"); + autoEncoding = encoding; + } } else { @@ -128,7 +160,9 @@ static int appStoreDataService(HttpService *service, HttpResponse *response) if (skipEnableJson != NULL) { - skipEnable = jsonAsBoolean(skipEnableJson); + if (jsonAsBoolean(skipEnableJson)) { + skipEnable = true; + } } if (registryJson == NULL) @@ -148,6 +182,8 @@ static int appStoreDataService(HttpService *service, HttpResponse *response) char *registry = jsonAsString(registryJson); char *handler = jsonAsString(handlerJson); + char *type = "string"; + char cmd[10280]; int bufferPos = 0; @@ -172,7 +208,7 @@ static int appStoreDataService(HttpService *service, HttpResponse *response) "App Store call '%s' ended in rc=%d\n", cmd, retCode); if (!retCode) { - jsonPrinter *p = writeSuccess(response, retCode, "string"); + jsonPrinter *p = writeSuccess(response, retCode, type); jsonAddInt(p, "rc", retCode); jsonEnd(p); From 17cb912e98f32d308e3389592082c795c453ed01 Mon Sep 17 00:00:00 2001 From: Priyansh61 <21bec080@iiitdmj.ac.in> Date: Wed, 6 Sep 2023 16:46:52 +0530 Subject: [PATCH 3/3] Updated Changelog Signed-off-by: Priyansh61 <21bec080@iiitdmj.ac.in> --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f32605a..3fad63f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to the Zlux App Manager will be documented in this file. +## `2.11.0` +- Added App Store for installing plugins in Zowe Desktop + ## `2.10.0` - Bugfix: Fixed a timing issue with the iframe-adapter for Firefox (#532)