From 8cc7cd8cac97ab213334b603ccb4f4d2c2114373 Mon Sep 17 00:00:00 2001 From: Joe Devlin Date: Thu, 14 Jul 2022 09:47:22 -0500 Subject: [PATCH 01/28] bad zero extension of 31 bit pointers breaking dynalloc in AMODE 64 Signed-off-by: Joe Devlin --- c/dynalloc.c | 8 ++++---- h/dynalloc.h | 4 ++-- h/zowetypes.h | 4 +++- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/c/dynalloc.c b/c/dynalloc.c index dc35a2eb0..d028f452d 100644 --- a/c/dynalloc.c +++ b/c/dynalloc.c @@ -730,7 +730,7 @@ int DeallocDDName(char *ddname) { ); below2G->plistAddress = - (SVC99RequestBlock * __ptr32)INT2PTR((int)&below2G->plist | 0x80000000); + (SVC99RequestBlock * __ptr32)INT2PTR32((int)&below2G->plist | 0x80000000); SVC99RequestBlock *plist = &below2G->plist; unsigned int textUnitCount = TEXT_UNIT_ARRAY_SIZE(below2G->textUnits); @@ -921,7 +921,7 @@ int unallocDataset(DynallocInputParms *inputParms, int *reasonCode) { ); below2G->requestBlockAddress = - (SVC99RequestBlock * __ptr32)INT2PTR((int)&below2G->requestBlock | 0x80000000); + (SVC99RequestBlock * __ptr32)INT2PTR32((int)&below2G->requestBlock | 0x80000000); SVC99RequestBlock *requestBlock = &below2G->requestBlock; unsigned int textUnitCount = TEXT_UNIT_ARRAY_SIZE(below2G->textUnits); @@ -991,7 +991,7 @@ int dynallocAllocDataset(const DynallocDatasetName *dsn, ); below2G->requestBlockAddress = - (SVC99RequestBlock * __ptr32)INT2PTR((int)&below2G->requestBlock | 0x80000000); + (SVC99RequestBlock * __ptr32)INT2PTR32((int)&below2G->requestBlock | 0x80000000); SVC99RequestBlock *requestBlock = &below2G->requestBlock; unsigned textUnitCount = TEXT_UNIT_ARRAY_SIZE(below2G->textUnits); @@ -1091,7 +1091,7 @@ static int dynallocUnallocDatasetByDDNameInternal(const DynallocDDName *ddName, ); below2G->requestBlockAddress = - (SVC99RequestBlock * __ptr32)INT2PTR((int)&below2G->requestBlock | 0x80000000); + (SVC99RequestBlock * __ptr32)INT2PTR32((int)&below2G->requestBlock | 0x80000000); SVC99RequestBlock *requestBlock = &below2G->requestBlock; unsigned textUnitCount = TEXT_UNIT_ARRAY_SIZE(below2G->textUnits); diff --git a/h/dynalloc.h b/h/dynalloc.h index 7cebd8e4a..1373cf44b 100644 --- a/h/dynalloc.h +++ b/h/dynalloc.h @@ -25,8 +25,8 @@ #error z/OS targets are supported only #endif -#define turn_on_HOB(x) x = (TextUnit* __ptr32) INT2PTR((int) x | 0x80000000) -#define turn_off_HOB(x) x = (TextUnit* __ptr32) INT2PTR((int) x & 0x7FFFFFFF) +#define turn_on_HOB(x) x = (TextUnit* __ptr32) INT2PTR32((int) x | 0x80000000) +#define turn_off_HOB(x) x = (TextUnit* __ptr32) INT2PTR32((int) x & 0x7FFFFFFF) #define S99VRBAL 0x01 /* Allocation */ #define S99VRBUN 0x02 /* Unallocation */ diff --git a/h/zowetypes.h b/h/zowetypes.h index 52df8f73c..86c1cf7dd 100644 --- a/h/zowetypes.h +++ b/h/zowetypes.h @@ -280,7 +280,8 @@ typedef uint64_t uint64; #define INT64_INT(x) ((int)x) #define INT_INT64(x) ((int64)x) #define CHARPTR_INT64(x) ((int64)x) -#define INT2PTR(x) ((void*)((int64_t)(x))) +#define INT2PTR(x) ((void*)(((uint64_t)(x))&0xffffffffl)) +#define INT2PTR32(x) ((void *__ptr32)(((uint64_t)(x))&0xffffffffl)) #define INT64_LL(x) ((long long)(x)) #define UINT64_ULL(x) ((unsigned long long)(x)) @@ -293,6 +294,7 @@ typedef unsigned long long uint64; #define INT_INT64(x) ((int64)x) #define CHARPTR_INT64(x) ((int64)((int)x)) #define INT2PTR(x) ((void*)(x)) +#define INT2PTR32(x) ((void*)(x)) #define INT64_LL(x) ((long long)(x)) #define UINT64_ULL(x) ((unsigned long long)(x)) From d17728caf8085f5d506fa71863d4458321038cf3 Mon Sep 17 00:00:00 2001 From: Joe Devlin Date: Thu, 14 Jul 2022 22:10:45 -0500 Subject: [PATCH 02/28] more QJS functions for config semantic validation Signed-off-by: Joe Devlin --- build/build_cmgr_xlclang.sh | 17 +- c/configmgr.c | 2 +- c/embeddedjs.c | 306 ++++----------------------- c/httpclient.c | 10 +- c/qjsnet.c | 376 +++++++++++++++++++++++++++++++++ c/qjszos.c | 403 ++++++++++++++++++++++++++++++++++++ c/tls.c | 3 +- h/ejsinternal.h | 48 +++++ h/httpclient.h | 1 + h/qjsnet.h | 32 +++ h/qjszos.h | 32 +++ tests/js/net1.js | 51 +++++ tests/js/zos1.js | 27 +++ 13 files changed, 1039 insertions(+), 269 deletions(-) create mode 100644 c/qjsnet.c create mode 100644 c/qjszos.c create mode 100644 h/ejsinternal.h create mode 100644 h/qjsnet.h create mode 100644 h/qjszos.h create mode 100644 tests/js/net1.js create mode 100644 tests/js/zos1.js diff --git a/build/build_cmgr_xlclang.sh b/build/build_cmgr_xlclang.sh index 6c8a32917..b78293f3f 100755 --- a/build/build_cmgr_xlclang.sh +++ b/build/build_cmgr_xlclang.sh @@ -52,6 +52,9 @@ VERSION="\"${VERSION}\"" rm -f "${COMMON}/bin/configmgr" +GSKDIR=/usr/lpp/gskssl +GSKINC="${GSKDIR}/include" + xlclang \ -c \ -q64 \ @@ -96,9 +99,11 @@ xlclang \ -D_XOPEN_SOURCE=600 \ -D_OPEN_THREADS=1 \ -DNOIBMHTTP=1 \ + -DUSE_ZOWE_TLS=1 \ -DCMGRTEST=1 \ -I "${COMMON}/h" \ -I "${COMMON}/platform/posix" \ + -I ${GSKINC} \ -I "${DEPS_DESTINATION}/${LIBYAML}/include" \ -I "${DEPS_DESTINATION}/${QUICKJS}" \ -o "${COMMON}/bin/configmgr" \ @@ -122,22 +127,32 @@ xlclang \ ${COMMON}/c/collections.c \ ${COMMON}/c/configmgr.c \ ${COMMON}/c/embeddedjs.c \ + ${COMMON}/c/fdpoll.c \ + ${COMMON}/c/http.c \ + ${COMMON}/c/httpclient.c \ ${COMMON}/c/json.c \ + ${COMMON}/c/jcsi.c \ ${COMMON}/c/jsonschema.c \ ${COMMON}/c/le.c \ ${COMMON}/c/logging.c \ ${COMMON}/c/microjq.c \ ${COMMON}/c/parsetools.c \ ${COMMON}/c/pdsutil.c \ + ${COMMON}/c/qjsnet.c \ + ${COMMON}/c/qjszos.c \ ${COMMON}/platform/posix/psxregex.c \ ${COMMON}/c/recovery.c \ ${COMMON}/c/scheduling.c \ + ${COMMON}/c/socketmgmt.c \ ${COMMON}/c/timeutls.c \ + ${COMMON}/c/tls.c \ ${COMMON}/c/utils.c \ ${COMMON}/c/xlate.c \ ${COMMON}/c/yaml2json.c \ ${COMMON}/c/zos.c \ - ${COMMON}/c/zosfile.c + ${COMMON}/c/zosfile.c \ + ${GSKDIR}/lib/GSKSSL64.x \ + ${GSKDIR}/lib/GSKCMS64.x #then # echo "Build successful" # ls -l "${COMMON}/bin" diff --git a/c/configmgr.c b/c/configmgr.c index 28b2d827d..b0f2b7328 100644 --- a/c/configmgr.c +++ b/c/configmgr.c @@ -1849,7 +1849,7 @@ int main(int argc, char **argv){ fflush(stderr); */ int evalStatus = ejsEvalFile(ejs,filename,EJS_LOAD_IS_MODULE); - // printf("Done with EJS: File eval returns %d_______________________________________________\n",evalStatus); + /* printf("Done with EJS: File eval returns %d_______________________________________________\n",evalStatus); */ } else { return simpleMain(argc,argv); } diff --git a/c/embeddedjs.c b/c/embeddedjs.c index 5d1961e3e..2fb00dab6 100644 --- a/c/embeddedjs.c +++ b/c/embeddedjs.c @@ -48,6 +48,9 @@ #include "json.h" #include "charsets.h" #include "embeddedjs.h" +#include "ejsinternal.h" +#include "qjszos.h" +#include "qjsnet.h" #include "cutils.h" #include "quickjs-libc.h" @@ -65,24 +68,9 @@ typedef int64_t ssize_t; #include "porting/polyfill.h" -int __atoe_l(char *bufferptr, int leng); -int __etoa_l(char *bufferptr, int leng); - #endif -static int convertToNative(char *buf, size_t size) { -#ifdef __ZOWE_OS_ZOS - return __atoe_l(buf, size); -#endif - return 0; -} - -static int convertFromNative(char *buf, size_t size) { -#ifdef __ZOWE_OS_ZOS - return __etoa_l(buf, size); -#endif - return 0; -} +#include "nativeconversion.h" struct trace_malloc_data { uint8_t *base; @@ -263,9 +251,39 @@ int ejsEvalFile(EmbeddedJS *ejs, const char *filename, int loadMode){ /* Some conveniences for building 'native' modules */ -static JSValue makeObjectAndErrorArray(JSContext *ctx, - JSValue obj, - int err){ +void ejsDefinePropertyValueStr(JSContext *ctx, JSValueConst obj, + const char *propertyName, JSValue value, int flags){ + int len = strlen(propertyName); + char asciiName[len+1]; + memcpy(asciiName,propertyName,len+1); + convertFromNative(asciiName,len); + JS_DefinePropertyValueStr(ctx, obj, asciiName, value, flags); +} + +JSValue newJSStringFromNative(JSContext *ctx, char *str, int len){ + while ((len > 0) && (str[len-1] <= ' ')) len--; + char native[len+1]; + memcpy(native,str,len); + native[len] = 0; + convertFromNative(native,len); + + return JS_NewStringLen(ctx, native, len); +} + +char *nativeString(JSContext *ctx, JSValue str, ShortLivedHeap *heapOrNull){ + size_t len; + const char *asciiValue = JS_ToCStringLen(ctx, &len, str); + char *nativeValue = (heapOrNull ? + SLHAlloc(heapOrNull, len+1) : + safeMalloc(len+1,"nativeString")); + memcpy(nativeValue,asciiValue,len+1); + convertToNative(nativeValue,len+1); + return nativeValue; +} + +JSValue ejsMakeObjectAndErrorArray(JSContext *ctx, + JSValue obj, + int err){ JSValue arr; if (JS_IsException(obj)) return obj; @@ -308,244 +326,6 @@ static JSValue makeStatusErrnoAndDetailArray(JSContext *ctx, return arr; } -#define NATIVE_STR(name,nativeName,i) const char *name; \ - size_t name##Len; \ - name = JS_ToCStringLen(ctx, &name##Len, argv[i]); \ - if (!name) return JS_EXCEPTION; \ - char nativeName[ name##Len + 1 ]; \ - memcpy(nativeName, name, name##Len+1); \ - convertToNative(nativeName, (int) name##Len); - -/* zos module */ - -static JSValue zosChangeTag(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv){ - size_t len; - const char *pathname = JS_ToCStringLen(ctx, &len, argv[0]); - if (!pathname){ - return JS_EXCEPTION; - } - /* - Since target function is QASCII, do NOT convert the path - */ - - int ccsidInt = 0; - JS_ToInt32(ctx, &ccsidInt, argv[1]); - unsigned short ccsid = (unsigned short)ccsidInt; -#ifdef __ZOWE_OS_ZOS - int status = tagFile(pathname, ccsid); -#else - int status = -1; -#endif - JS_FreeCString(ctx,pathname); - return JS_NewInt64(ctx,(int64_t)status); -} - -static JSValue zosChangeExtAttr(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv){ - size_t len; - const char *pathname = JS_ToCStringLen(ctx, &len, argv[0]); - if (!pathname){ - return JS_EXCEPTION; - } - /* - Since target function is QASCII, do NOT convert the path - */ - - int extattrInt = 0; - JS_ToInt32(ctx, &extattrInt, argv[1]); - unsigned char extattr = (unsigned char)extattrInt; - int onOffInt = JS_ToBool(ctx, argv[2]); -#ifdef __ZOWE_OS_ZOS - int status = changeExtendedAttributes(pathname, extattr, onOffInt ? true : false); -#else - int status = -1; -#endif - JS_FreeCString(ctx,pathname); - return JS_NewInt64(ctx,(int64_t)status); -} - -static void ejsDefinePropertyValueStr(JSContext *ctx, JSValueConst obj, - const char *propertyName, JSValue value, int flags){ - int len = strlen(propertyName); - char asciiName[len+1]; - memcpy(asciiName,propertyName,len+1); - convertFromNative(asciiName,len); - JS_DefinePropertyValueStr(ctx, obj, asciiName, value, flags); -} - - -static JSValue zosChangeStreamCCSID(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv){ - int fd; - JS_ToInt32(ctx, &fd, argv[0]); - - int ccsidInt = 0; - JS_ToInt32(ctx, &ccsidInt, argv[1]); - unsigned short ccsid = (unsigned short)ccsidInt; -#ifdef __ZOWE_OS_ZOS - int status = convertOpenStream(fd, ccsid); -#else - int status = -1; -#endif - return JS_NewInt64(ctx,(int64_t)status); -} - -/* return [obj, errcode] */ -static JSValue zosStat(JSContext *ctx, JSValueConst this_val, - int argc, JSValueConst *argv){ - const char *path; - int err, res; - struct stat st; - JSValue obj; - size_t len; - - path = JS_ToCStringLen(ctx, &len, argv[0]); - if (!path){ - return JS_EXCEPTION; - } - - char pathNative[len+1]; - memcpy(pathNative,path,len+1); - convertToNative(pathNative,len); - - res = stat(pathNative, &st); - - JS_FreeCString(ctx, path); - if (res < 0){ - err = errno; - obj = JS_NULL; - } else{ - err = 0; - obj = JS_NewObject(ctx); - if (JS_IsException(obj)){ - return JS_EXCEPTION; - } - ejsDefinePropertyValueStr(ctx, obj, "dev", - JS_NewInt64(ctx, st.st_dev), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "ino", - JS_NewInt64(ctx, st.st_ino), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "mode", - JS_NewInt32(ctx, st.st_mode), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "nlink", - JS_NewInt64(ctx, st.st_nlink), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "uid", - JS_NewInt64(ctx, st.st_uid), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "gid", - JS_NewInt64(ctx, st.st_gid), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "rdev", - JS_NewInt64(ctx, st.st_rdev), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "size", - JS_NewInt64(ctx, st.st_size), - JS_PROP_C_W_E); -#if !defined(_WIN32) - ejsDefinePropertyValueStr(ctx, obj, "blocks", - JS_NewInt64(ctx, st.st_blocks), - JS_PROP_C_W_E); -#endif -#if defined(_WIN32) || defined(__MVS__) /* JOENemo */ - ejsDefinePropertyValueStr(ctx, obj, "atime", - JS_NewInt64(ctx, (int64_t)st.st_atime * 1000), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "mtime", - JS_NewInt64(ctx, (int64_t)st.st_mtime * 1000), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "ctime", - JS_NewInt64(ctx, (int64_t)st.st_ctime * 1000), - JS_PROP_C_W_E); -#elif defined(__APPLE__) - ejsDefinePropertyValueStr(ctx, obj, "atime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_atimespec)), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "mtime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_mtimespec)), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "ctime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_ctimespec)), - JS_PROP_C_W_E); -#else - ejsDefinePropertyValueStr(ctx, obj, "atime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_atim)), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "mtime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_mtim)), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "ctime", - JS_NewInt64(ctx, timespec_to_ms(&st.st_ctim)), - JS_PROP_C_W_E); -#endif - /* Non-standard, not-even-close-to-standard attributes. */ -#ifdef __ZOWE_OS_ZOS - ejsDefinePropertyValueStr(ctx, obj, "extattrs", - JS_NewInt64(ctx, (int64_t)st.st_genvalue&EXTATTR_MASK), - JS_PROP_C_W_E); - struct file_tag *tagInfo = &st.st_tag; - ejsDefinePropertyValueStr(ctx, obj, "isText", - JS_NewBool(ctx, tagInfo->ft_txtflag), - JS_PROP_C_W_E); - ejsDefinePropertyValueStr(ctx, obj, "ccsid", - JS_NewInt64(ctx, (int64_t)(tagInfo->ft_ccsid)), - JS_PROP_C_W_E); -#endif - } - return makeObjectAndErrorArray(ctx, obj, err); -} - -static const char changeTagASCII[10] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x54, 0x61, 0x67, 0x00}; -static const char changeExtAttrASCII[14] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x45, 0x78, 0x74, 0x41, 0x74, 0x74, 0x72, 0x00}; -static const char changeStreamCCSIDASCII[18] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, - 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x43, 0x53, 0x49, 0x44, 0x00}; -static const char zstatASCII[6] ={ 0x7A, 0x73, 0x74, 0x61, 0x74, 0}; - -static const char EXTATTR_SHARELIB_ASCII[17] = { 0x45, 0x58, 0x54, 0x41, 0x54, 0x54, 0x52, 0x5f, - 0x53, 0x48, 0x41, 0x52, 0x45, 0x4c, 0x49, 0x42, 0x0}; - -static const char EXTATTR_PROGCTL_ASCII[16] = { 0x45, 0x58, 0x54, 0x41, 0x54, 0x54, 0x52, 0x5f, - 0x50, 0x52, 0x4f, 0x47, 0x43, 0x54, 0x4c, 0x00}; - -#ifndef __ZOWE_OS_ZOS -/* stub the constants that non-ZOS does not define */ -#define EXTATTR_SHARELIB 1 -#define EXTATTR_PROGCTL 1 -#endif - -static const JSCFunctionListEntry zosFunctions[] = { - JS_CFUNC_DEF(changeTagASCII, 2, zosChangeTag), - JS_CFUNC_DEF(changeExtAttrASCII, 3, zosChangeExtAttr), - JS_CFUNC_DEF(changeStreamCCSIDASCII, 2, zosChangeStreamCCSID), - JS_CFUNC_DEF(zstatASCII, 1, zosStat), - JS_PROP_INT32_DEF(EXTATTR_SHARELIB_ASCII, EXTATTR_SHARELIB, JS_PROP_CONFIGURABLE ), - JS_PROP_INT32_DEF(EXTATTR_PROGCTL_ASCII, EXTATTR_PROGCTL, JS_PROP_CONFIGURABLE ), - /* ALSO, "cp" with magic ZOS-unix see fopen not fileOpen */ -}; - - -static int ejsInitZOSCallback(JSContext *ctx, JSModuleDef *m){ - - /* JSValue = proto = JS_NewObject(ctx); */ - JS_SetModuleExportList(ctx, m, zosFunctions, countof(zosFunctions)); - return 0; -} - -JSModuleDef *ejsInitModuleZOS(JSContext *ctx, const char *module_name){ - JSModuleDef *m; - m = JS_NewCModule(ctx, module_name, ejsInitZOSCallback); - if (!m){ - return NULL; - } - JS_AddModuleExportList(ctx, m, zosFunctions, countof(zosFunctions)); - - return m; -} /*** POSIX Module - low level services not in the QuickJS os module. ***/ @@ -781,9 +561,9 @@ static JSValue xplatformDirname(JSContext *ctx, JSValueConst this_val, char dirnameASCII[dirLen+1]; memcpy(dirnameASCII,dirname,dirLen+1); convertFromNative(dirnameASCII,dirLen); - return makeObjectAndErrorArray(ctx, JS_NewString(ctx, dirnameASCII), 0); + return ejsMakeObjectAndErrorArray(ctx, JS_NewString(ctx, dirnameASCII), 0); } else { - return makeObjectAndErrorArray(ctx, JS_NULL, status); + return ejsMakeObjectAndErrorArray(ctx, JS_NULL, status); } } @@ -930,6 +710,7 @@ static JSValue xplatformGetpid(JSContext *ctx, JSValueConst this_val, return JS_NewInt64(ctx,(int64_t)pid); } + static char fileCopyASCII[9] = {0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x00 }; static char fileCopyConvertedASCII[18] = {0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x70, 0x79, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x65, 0x64, 0x00 }; @@ -943,6 +724,7 @@ static char AUTO_DETECT_ASCII[12] = {0x41, 0x55, 0x54, 0x4f, 0x5f, 0x44, 0x45, 0 static char NO_CONVERT_ASCII[11] = {0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x4e, 0x56, 0x45, 0x52, 0x54, 0x00 }; static char loadFileUTF8ASCII[13] = {0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x54, 0x46, 0x38, 0x00 }; static char storeFileUTF8ASCII[14] = {0x73, 0x74, 0x6f, 0x72, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x55, 0x54, 0x46, 0x38, 0x00 }; +static char tcpPingASCII[8] ={0x74, 0x63, 0x70, 0x50, 0x69, 0x6e, 0x67, 0x00}; static const JSCFunctionListEntry xplatformFunctions[] = { JS_CFUNC_DEF(fileCopyASCII, 2, xplatformFileCopy), @@ -1301,6 +1083,7 @@ static char asciiExperiment[11] ={ 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0}; static char asciiZOS[4] = { 0x7a, 0x6F, 0x73, 0}; +static char asciiNet[4] = { 0x6e, 0x65, 0x74, 0}; static char asciiPosix[6] = { 0x70, 0x6F, 0x73, 0x69, 0x78, 0}; static char asciiXPlatform[10] = { 0x78, 0x70, 0x6C, 0x61, 0x74, 0x66, 0x6F, 0x72, 0x6D, 0}; @@ -1603,6 +1386,7 @@ static void initContextModules(JSContext *ctx, EJSNativeModule **nativeModules, js_init_module_os(ctx, asciiOS); js_init_module_experiment(ctx, asciiExperiment); ejsInitModuleZOS(ctx, asciiZOS); + ejsInitModuleNet(ctx, asciiNet); ejsInitModulePOSIX(ctx, asciiPosix); ejsInitModuleXPlatform(ctx, asciiXPlatform); /* printf("after init experiment\n");*/ @@ -1997,13 +1781,11 @@ static bool evaluationVisitor(void *context, Json *json, Json *parent, char *key char asciiSource[sourceLen + 1]; snprintf (asciiSource, sourceLen + 1, "%.*s", (int)sourceLen, source); convertFromNative(asciiSource, sourceLen); - printf("should evaluate: %s\n",source); + /* printf("should evaluate: %s\n",source); */ int evalStatus = 0; char embedded[] = ""; convertFromNative(embedded, sizeof(embedded)); - printf("in ascii\n"); - dumpbuffer(asciiSource,strlen(asciiSource)); JSValue output = ejsEvalBuffer1(ejs,asciiSource,strlen(asciiSource),embedded,0,&evalStatus); if (evalStatus){ printf("failed to evaluate '%s', status=%d\n",source,evalStatus); diff --git a/c/httpclient.c b/c/httpclient.c index bda259d9b..3d2c40f3c 100644 --- a/c/httpclient.c +++ b/c/httpclient.c @@ -20,6 +20,8 @@ #include #endif +#include "zowetypes.h" +#include "alloc.h" #include "utils.h" #include "xlate.h" #include "bpxnet.h" @@ -524,9 +526,9 @@ static int processHttpResponseFragment(HttpResponseParser *parser, void httpClientSettingsDestroy(HttpClientSettings *settings) { if (settings) { if (settings->host) { - safeFree(settings->host, 1 + strlen(settings->host)); + safeFree((char*)settings->host, 1 + strlen(settings->host)); } - safeFree(settings, sizeof(HttpClientSettings)); + safeFree((char*)settings, sizeof(HttpClientSettings)); } } @@ -552,7 +554,7 @@ void httpClientContextDestroy(HttpClientContext *ctx) { freeSocketAddr(ctx->serverAddress); } memset(ctx, 0x00, sizeof(HttpClientContext)); - safeFree(ctx, sizeof(HttpClientContext)); + safeFree((char*)ctx, sizeof(HttpClientContext)); } } @@ -638,7 +640,7 @@ void httpClientSessionDestroy(HttpClientSession *session) { SLHFree(session->slh); } memset(session, 0x00, sizeof(HttpClientSession)); - safeFree(session, sizeof(HttpClientSession)); + safeFree((char*)session, sizeof(HttpClientSession)); } } diff --git a/c/qjsnet.c b/c/qjsnet.c new file mode 100644 index 000000000..ac2fcfbc0 --- /dev/null +++ b/c/qjsnet.c @@ -0,0 +1,376 @@ +/* + 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 +#include +#include +#include "metalio.h" +#include "qsam.h" + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "openprims.h" +#include "bpxnet.h" +#include "unixfile.h" +#include "json.h" +#include "xlate.h" +#include "charsets.h" +#include "embeddedjs.h" +#include "ejsinternal.h" +#include "http.h" +#include "httpclient.h" +#include "tls.h" +#include "qjsnet.h" + +#ifdef __ZOWE_OS_ZOS + +#include "porting/polyfill.h" + +#endif + +#include "nativeconversion.h" + +/* zos module - moved to its own file because it may grow a lot */ + + +static JSValue netTCPPing(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + if (argc != 3){ + return JS_EXCEPTION; + } + NATIVE_STR(hostname,nativeHostname,0); + if (!hostname){ + return JS_EXCEPTION; + } + int port; + JS_ToInt32(ctx, &port, argv[1]); + + int waitMS; + JS_ToInt32(ctx, &waitMS, argv[2]); + + JSValue result = JS_NewObject(ctx); + if (JS_IsException(result)){ + return JS_EXCEPTION; + } + + bool ok = true; + char *message = NULL; + InetAddr *serverIPAddr = getAddressByName(nativeHostname); + if (NULL == serverIPAddr || serverIPAddr->data.data4.addrBytes == 0){ + message = "unknown or malformed host address"; + ok = false; + } + SocketAddress *serverAddress = NULL; + if (ok){ + serverAddress = makeSocketAddr(serverIPAddr, port); + if (NULL == serverAddress) { + message = "failed to make socket address"; + ok = false; + } + } + Socket *socket = NULL; + int returnCode = 0; + int reasonCode = 0; + + if (ok){ + socket = tcpClient2(serverAddress, waitMS, &returnCode, &reasonCode); + + if (socket == NULL || returnCode != 0){ + message = "failed to connect socket to host"; + ejsDefinePropertyValueStr(ctx, result, "returnCode",JS_NewInt32(ctx, returnCode), JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, result, "reasonCode",JS_NewInt32(ctx, reasonCode), JS_PROP_C_W_E); + ok = false; + } + } + if (message){ + ejsDefinePropertyValueStr(ctx, result, "error", + newJSStringFromNative(ctx, message, strlen(message)), + JS_PROP_C_W_E); + } + if (serverAddress){ + freeSocketAddr(serverAddress); + } + if (socket){ + socketClose(socket,&returnCode,&reasonCode); + socketFree(socket); + } + + return result; +} + +static TlsSettings *defaultTLSSettings = NULL; + +static char truststoreASCII[11] ={0x74, 0x72, 0x75, 0x73, 0x74, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x00}; +static char passwordASCII[9] ={0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x00}; +static char stashASCII[6] ={0x73, 0x74, 0x61, 0x73, 0x68, 0x00}; +static char labelASCII[6] ={0x6c, 0x61, 0x62, 0x65, 0x6c, 0x00}; + + +static JSValue netTLSClientConfig(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + JSValue settings = argv[0]; + JSValueConst truststore = JS_GetPropertyStr(ctx, settings, truststoreASCII); + JSValueConst password = JS_GetPropertyStr(ctx, settings, passwordASCII); + JSValueConst stash = JS_GetPropertyStr(ctx, settings, stashASCII); + JSValueConst label = JS_GetPropertyStr(ctx, settings, labelASCII); + if (JS_IsUndefined(truststore)){ + return JS_EXCEPTION; + } + if (JS_IsUndefined(password) && JS_IsUndefined(stash)){ + return JS_EXCEPTION; + } + if (!JS_IsString(truststore) || + (!JS_IsUndefined(password) && !JS_IsString(password)) || + (!JS_IsUndefined(stash) && !JS_IsString(stash)) || + (!JS_IsUndefined(label) && !JS_IsString(label)) ){ + return JS_EXCEPTION; + } + if (defaultTLSSettings == NULL){ + defaultTLSSettings = (TlsSettings*)safeMalloc(sizeof(TlsSettings),"QJS Tls Settings"); + } + defaultTLSSettings->keyring = nativeString(ctx,truststore,NULL); + if (!JS_IsUndefined(password)){ + defaultTLSSettings->password = nativeString(ctx,password,NULL); + } + if (!JS_IsUndefined(stash)){ + defaultTLSSettings->stash = nativeString(ctx,stash,NULL); + } + if (!JS_IsUndefined(label)){ + defaultTLSSettings->label = nativeString(ctx,label,NULL); + } + return JS_NewInt64(ctx,(int64_t)0); +} + +static bool httpTrace = false; + +static int httpGet(bool isTLS, + char *host, + int port, + char *path, + char **content){ + TlsEnvironment *tlsEnv = NULL; + HttpClientSettings clientSettings; + HttpClientContext *httpClientContext = NULL; + HttpClientSession *session = NULL; + + int status = 0; + char buffer[2048]; + LoggingContext *loggingContext = getLoggingContext(); + + do{ + clientSettings.host = host; + clientSettings.port = port; + clientSettings.recvTimeoutSeconds = 10; + + if (isTLS){ + status = tlsInit(&tlsEnv, defaultTLSSettings); + if (status){ + if (httpTrace){ + printf ("failed to init tls environment, rc=%d (%s)\n", status, tlsStrError(status)); + } + } + status = httpClientContextInitSecure(&clientSettings, loggingContext, tlsEnv, &httpClientContext); + } else{ + status = httpClientContextInit(&clientSettings, loggingContext, &httpClientContext); + } + + if (status){ + if (httpTrace){ + printf("error in httpcb ctx init: %d\n", status); + } + break; + } + if (httpTrace){ + printf("successfully initialized http client\n"); + } + status = httpClientSessionInit(httpClientContext, &session); + if (status){ + if (httpTrace){ + printf("error initing session: %d\n", status); + } + break; + } + + if (httpTrace){ + printf("successfully inited session\n"); + } + + status = httpClientSessionStageRequest(httpClientContext, session, "GET", path, NULL, NULL, NULL, 0); + if (status){ + if (httpTrace){ + printf("error staging request: %d\n", status); + } + break; + } + if (httpTrace){ + printf("successfully staged request\n"); + } + + status = httpClientSessionSend(httpClientContext, session); + if (status){ + if (httpTrace){ + printf("error sending request: %d\n", status); + } + break; + } + if (httpTrace){ + printf("successfully sent request\n"); + } + /* need to call receive native in a loop*/ + int quit = 0; + while (!quit){ + status = httpClientSessionReceiveNative(httpClientContext, session, 1024); + if (status != 0){ + if (httpTrace){ + printf("error receiving request: %d\n", status); + } + break; + } + if (session->response != NULL){ + if (httpTrace){ + printf("received valid response!\n"); + } + quit = 1; + break; + } + if (httpTrace){ + printf("looping\n"); + } + } + if (quit){ + char *response = safeMalloc(session->response->contentLength + 1, "response"); + memcpy(response,session->response->body, session->response->contentLength); + response[session->response->contentLength] = '\0'; + *content = response; + } else{ + *content = NULL; + } + } while (0); + + if (httpTrace){ + printf("httpGet ending with status: %d\n", status); + } + return status; +} + + +static JSValue netHttpContentAsText(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + if (argc != 4){ + return JS_EXCEPTION; + } + if (!JS_IsString(argv[0])){ + return JS_EXCEPTION; + } + NATIVE_STR(schema,nativeSchema,0); + if (!JS_IsString(argv[1])){ + return JS_EXCEPTION; + } + NATIVE_STR(host,nativeHost,1); + int port; + if (!JS_IsNumber(argv[2])){ + return JS_EXCEPTION; + } + JS_ToInt32(ctx, &port, argv[2]); + if (!JS_IsString(argv[3])){ + return JS_EXCEPTION; + } + NATIVE_STR(path,nativePath,3); + + int status = 0; + bool isTLS = !strcmp(nativeSchema,"https"); + if (isTLS && (defaultTLSSettings == NULL)){ + status = HTTP_CLIENT_TLS_NOT_CONFIGURED; + } + + char *content = NULL; + if (!status){ + status = httpGet(isTLS,nativeHost,port,nativePath,&content); + } + + JS_FreeCString(ctx,schema); + JS_FreeCString(ctx,host); + JS_FreeCString(ctx,path); + + JSValue result = (status ? + JS_NULL : + JS_NewString(ctx, content)); + + return ejsMakeObjectAndErrorArray(ctx, result, status); +} + +static char tcpPingASCII[8] ={0x74, 0x63, 0x70, 0x50, 0x69, 0x6e, 0x67, 0x00}; +static char tlsClientConfigASCII[16] ={0x74, 0x6c, 0x73, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x00}; +static char httpContentAsTextASCII[18] ={ 0x68, 0x74, 0x74, 0x70, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x41, 0x73, 0x54, 0x65, 0x78, + 0x74, 0x00}; + +static const JSCFunctionListEntry netFunctions[] = { + JS_CFUNC_DEF(tcpPingASCII, 3, netTCPPing), + JS_CFUNC_DEF(tlsClientConfigASCII, 1, netTLSClientConfig), + JS_CFUNC_DEF(httpContentAsTextASCII, 4, netHttpContentAsText), + +}; + +int ejsInitNetCallback(JSContext *ctx, JSModuleDef *m){ + + /* JSValue = proto = JS_NewObject(ctx); */ + JS_SetModuleExportList(ctx, m, netFunctions, countof(netFunctions)); + return 0; +} + +JSModuleDef *ejsInitModuleNet(JSContext *ctx, const char *moduleName){ + JSModuleDef *m; + m = JS_NewCModule(ctx, moduleName, ejsInitNetCallback); + if (!m){ + return NULL; + } + JS_AddModuleExportList(ctx, m, netFunctions, countof(netFunctions)); + return m; +} + + +/* + 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. +*/ + diff --git a/c/qjszos.c b/c/qjszos.c new file mode 100644 index 000000000..dfbdc8ee5 --- /dev/null +++ b/c/qjszos.c @@ -0,0 +1,403 @@ +/* + 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 +#include +#include +#include "metalio.h" +#include "qsam.h" + +#else + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + +#include "zowetypes.h" +#include "alloc.h" +#include "utils.h" +#include "openprims.h" +#include "bpxnet.h" +#include "unixfile.h" +#include "json.h" +#include "charsets.h" +#include "embeddedjs.h" +#include "ejsinternal.h" +#include "jcsi.h" + +#ifdef __ZOWE_OS_ZOS + +#include "porting/polyfill.h" + +#endif + +#include "nativeconversion.h" + +/* zos module - moved to its own file because it may grow a lot */ + +static JSValue zosChangeTag(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + size_t len; + const char *pathname = JS_ToCStringLen(ctx, &len, argv[0]); + if (!pathname){ + return JS_EXCEPTION; + } + /* + Since target function is QASCII, do NOT convert the path + */ + + int ccsidInt = 0; + JS_ToInt32(ctx, &ccsidInt, argv[1]); + unsigned short ccsid = (unsigned short)ccsidInt; +#ifdef __ZOWE_OS_ZOS + int status = tagFile(pathname, ccsid); +#else + int status = -1; +#endif + JS_FreeCString(ctx,pathname); + return JS_NewInt64(ctx,(int64_t)status); +} + +static JSValue zosChangeExtAttr(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + size_t len; + const char *pathname = JS_ToCStringLen(ctx, &len, argv[0]); + if (!pathname){ + return JS_EXCEPTION; + } + /* + Since target function is QASCII, do NOT convert the path + */ + + int extattrInt = 0; + JS_ToInt32(ctx, &extattrInt, argv[1]); + unsigned char extattr = (unsigned char)extattrInt; + int onOffInt = JS_ToBool(ctx, argv[2]); +#ifdef __ZOWE_OS_ZOS + int status = changeExtendedAttributes(pathname, extattr, onOffInt ? true : false); +#else + int status = -1; +#endif + JS_FreeCString(ctx,pathname); + return JS_NewInt64(ctx,(int64_t)status); +} + +static JSValue zosChangeStreamCCSID(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + int fd; + JS_ToInt32(ctx, &fd, argv[0]); + + int ccsidInt = 0; + JS_ToInt32(ctx, &ccsidInt, argv[1]); + unsigned short ccsid = (unsigned short)ccsidInt; +#ifdef __ZOWE_OS_ZOS + int status = convertOpenStream(fd, ccsid); +#else + int status = -1; +#endif + return JS_NewInt64(ctx,(int64_t)status); +} + + +/* return [obj, errcode] */ +static JSValue zosStat(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + const char *path; + int err, res; + struct stat st; + JSValue obj; + size_t len; + + path = JS_ToCStringLen(ctx, &len, argv[0]); + if (!path){ + return JS_EXCEPTION; + } + + char pathNative[len+1]; + memcpy(pathNative,path,len+1); + convertToNative(pathNative,len); + + res = stat(pathNative, &st); + + JS_FreeCString(ctx, path); + if (res < 0){ + err = errno; + obj = JS_NULL; + } else{ + err = 0; + obj = JS_NewObject(ctx); + if (JS_IsException(obj)){ + return JS_EXCEPTION; + } + ejsDefinePropertyValueStr(ctx, obj, "dev", + JS_NewInt64(ctx, st.st_dev), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "ino", + JS_NewInt64(ctx, st.st_ino), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "mode", + JS_NewInt32(ctx, st.st_mode), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "nlink", + JS_NewInt64(ctx, st.st_nlink), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "uid", + JS_NewInt64(ctx, st.st_uid), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "gid", + JS_NewInt64(ctx, st.st_gid), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "rdev", + JS_NewInt64(ctx, st.st_rdev), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "size", + JS_NewInt64(ctx, st.st_size), + JS_PROP_C_W_E); +#if !defined(_WIN32) + ejsDefinePropertyValueStr(ctx, obj, "blocks", + JS_NewInt64(ctx, st.st_blocks), + JS_PROP_C_W_E); +#endif +#if defined(_WIN32) || defined(__MVS__) /* JOENemo */ + ejsDefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, (int64_t)st.st_atime * 1000), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, (int64_t)st.st_mtime * 1000), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, (int64_t)st.st_ctime * 1000), + JS_PROP_C_W_E); +#elif defined(__APPLE__) + ejsDefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_atimespec)), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_mtimespec)), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_ctimespec)), + JS_PROP_C_W_E); +#else + ejsDefinePropertyValueStr(ctx, obj, "atime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_atim)), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "mtime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_mtim)), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "ctime", + JS_NewInt64(ctx, timespec_to_ms(&st.st_ctim)), + JS_PROP_C_W_E); +#endif + /* Non-standard, not-even-close-to-standard attributes. */ +#ifdef __ZOWE_OS_ZOS + ejsDefinePropertyValueStr(ctx, obj, "extattrs", + JS_NewInt64(ctx, (int64_t)st.st_genvalue&EXTATTR_MASK), + JS_PROP_C_W_E); + struct file_tag *tagInfo = &st.st_tag; + ejsDefinePropertyValueStr(ctx, obj, "isText", + JS_NewBool(ctx, tagInfo->ft_txtflag), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, obj, "ccsid", + JS_NewInt64(ctx, (int64_t)(tagInfo->ft_ccsid)), + JS_PROP_C_W_E); +#endif + } + return ejsMakeObjectAndErrorArray(ctx, obj, err); +} + +static char *defaultCSIFields[] ={ "NAME ", "TYPE ", "VOLSER "}; +static int defaultCSIFieldCount = 3; + +/* return [obj, errcode] */ +static JSValue zosDatasetInfo(JSContext *ctx, JSValueConst this_val, + int argc, JSValueConst *argv){ + const char *dsn; + JSValue result; + size_t len; + bool trace = false; + + dsn = JS_ToCStringLen(ctx, &len, argv[0]); + if (!dsn){ + return JS_EXCEPTION; + } + + if (trace){ + printf("dslist start\n"); + } + char dsnNative[len+1]; + memcpy(dsnNative,dsn,len+1); + convertToNative(dsnNative,len); + + if (trace){ + printf("dsn %s\n",dsnNative); + } + + char *resumeNameArg = NULL; /* (resumeNameParam ? resumeNameParam->stringValue : NULL); */ + char *resumeCatalogNameArg = NULL; /* (resumeCatalogNameParam ? resumeCatalogNameParam->stringValue : NULL); */ + + csi_parmblock * __ptr32 returnParms = (csi_parmblock* __ptr32)safeMalloc31(sizeof(csi_parmblock),"CSI ParmBlock"); + + char *typesArg = "ADX"; + int datasetTypeCount = (typesArg == NULL) ? 3 : strlen(typesArg); + int workAreaSizeArg = 0; /* (workAreaSizeParam ? workAreaSizeParam->intValue : 0); */ + int fieldCount = defaultCSIFieldCount; + char **csiFields = defaultCSIFields; + + EntryDataSet *entrySet = returnEntries(dsnNative, + typesArg, datasetTypeCount, + workAreaSizeArg, + csiFields, fieldCount, + resumeNameArg, resumeCatalogNameArg, returnParms); + if (trace){ + printf("entrySet=0x%p\n",entrySet); + } + if (!entrySet){ + return JS_NULL; + } + char *resumeName = returnParms->resume_name; + char *catalogName = returnParms->catalog_name; + int isResume = (returnParms->is_resume == 'Y'); + result = JS_NewObject(ctx); + if (JS_IsException(result)){ + return JS_EXCEPTION; + } + if (isResume){ + ejsDefinePropertyValueStr(ctx, result, "resumeName", + newJSStringFromNative(ctx, resumeName, strlen(resumeName)), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, result, "resumeCatalogName", + newJSStringFromNative(ctx, catalogName, strlen(catalogName)), + JS_PROP_C_W_E); + } + + char volser[7]; + memset(volser,0,7); + + if (trace){ + printf("%d datasets\n",entrySet->length); + } + JSValue datasetArray = JS_NewArray(ctx); + if (JS_IsException(datasetArray)){ + return JS_EXCEPTION; + } + ejsDefinePropertyValueStr(ctx, result, "datasets", datasetArray, JS_PROP_C_W_E); + + int dsCount = 0; + for (int i = 0; i < entrySet->length; i++){ + EntryData *entry = entrySet->entries[i]; + + if (entry) { + JSValue info = JS_NewObject(ctx); + JS_DefinePropertyValueUint32(ctx, datasetArray, dsCount++, info, JS_PROP_C_W_E); + int fieldDataLength = entry->data.fieldInfoHeader.totalLength; + int entrySize = sizeof(EntryData)+fieldDataLength-4; /* -4 for the fact that the length is 4 from end of EntryData */ + int isMigrated = FALSE; + /* jsonStartObject(jPrinter, NULL); */ + int dsnLength = sizeof(entry->name); + char *datasetName = entry->name; + if (trace){ + printf("%*.*s\n",dsnLength,dsnLength,datasetName); + } + ejsDefinePropertyValueStr(ctx, info, "dsn", + newJSStringFromNative(ctx, datasetName, 44), + JS_PROP_C_W_E); + ejsDefinePropertyValueStr(ctx, info, "entryType", + newJSStringFromNative(ctx, &entry->type, 1), + JS_PROP_C_W_E); + } + } + + JS_FreeCString(ctx, dsn); + + return result; +} + +static const char changeTagASCII[10] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x54, 0x61, 0x67, 0x00}; +static const char changeExtAttrASCII[14] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x45, 0x78, 0x74, 0x41, 0x74, 0x74, 0x72, 0x00}; +static const char changeStreamCCSIDASCII[18] ={ 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, + 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x43, 0x53, 0x49, 0x44, 0x00}; +static const char zstatASCII[6] ={ 0x7A, 0x73, 0x74, 0x61, 0x74, 0}; + +static const char EXTATTR_SHARELIB_ASCII[17] = { 0x45, 0x58, 0x54, 0x41, 0x54, 0x54, 0x52, 0x5f, + 0x53, 0x48, 0x41, 0x52, 0x45, 0x4c, 0x49, 0x42, 0x0}; + +static const char EXTATTR_PROGCTL_ASCII[16] = { 0x45, 0x58, 0x54, 0x41, 0x54, 0x54, 0x52, 0x5f, + 0x50, 0x52, 0x4f, 0x47, 0x43, 0x54, 0x4c, 0x00}; + +static const char dslistASCII[7] ={ 0x64, 0x73, 0x6c, 0x69, 0x73, 0x74, 0x00}; + +#ifndef __ZOWE_OS_ZOS +/* stub the constants that non-ZOS does not define */ +#define EXTATTR_SHARELIB 1 +#define EXTATTR_PROGCTL 1 +#endif + +static const JSCFunctionListEntry zosFunctions[] = { + JS_CFUNC_DEF(changeTagASCII, 2, zosChangeTag), + JS_CFUNC_DEF(changeExtAttrASCII, 3, zosChangeExtAttr), + JS_CFUNC_DEF(changeStreamCCSIDASCII, 2, zosChangeStreamCCSID), + JS_CFUNC_DEF(zstatASCII, 1, zosStat), + JS_CFUNC_DEF(dslistASCII, 1, zosDatasetInfo), + JS_PROP_INT32_DEF(EXTATTR_SHARELIB_ASCII, EXTATTR_SHARELIB, JS_PROP_CONFIGURABLE ), + JS_PROP_INT32_DEF(EXTATTR_PROGCTL_ASCII, EXTATTR_PROGCTL, JS_PROP_CONFIGURABLE ), + /* ALSO, "cp" with magic ZOS-unix see fopen not fileOpen */ +}; + + +int ejsInitZOSCallback(JSContext *ctx, JSModuleDef *m){ + + /* JSValue = proto = JS_NewObject(ctx); */ + JS_SetModuleExportList(ctx, m, zosFunctions, countof(zosFunctions)); + return 0; +} + +JSModuleDef *ejsInitModuleZOS(JSContext *ctx, const char *module_name){ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, ejsInitZOSCallback); + if (!m){ + return NULL; + } + JS_AddModuleExportList(ctx, m, zosFunctions, countof(zosFunctions)); + loadCsi(); + return m; +} + + +/* + 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. +*/ diff --git a/c/tls.c b/c/tls.c index c7d27dad0..44a98aec3 100644 --- a/c/tls.c +++ b/c/tls.c @@ -8,6 +8,7 @@ Copyright Contributors to the Zowe Project. */ #include +#include #include #include "alloc.h" #include "bpxnet.h" @@ -163,4 +164,4 @@ const char *tlsStrError(int rc) { SPDX-License-Identifier: EPL-2.0 Copyright Contributors to the Zowe Project. -*/ \ No newline at end of file +*/ diff --git a/h/ejsinternal.h b/h/ejsinternal.h new file mode 100644 index 000000000..6e4514487 --- /dev/null +++ b/h/ejsinternal.h @@ -0,0 +1,48 @@ +/* + 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. +*/ + +#ifndef __ZOWE_EJSINTERNAL__ +#define __ZOWE_EJSINTERNAL__ 1 + +#include "zowetypes.h" +#include "cutils.h" +#include "quickjs-libc.h" + + +JSValue ejsMakeObjectAndErrorArray(JSContext *ctx, + JSValue obj, + int err); + +void ejsDefinePropertyValueStr(JSContext *ctx, JSValueConst obj, + const char *propertyName, JSValue value, int flags); + +JSValue newJSStringFromNative(JSContext *ctx, char *str, int len); +char *nativeString(JSContext *ctx, JSValue str, ShortLivedHeap *heapOrNull); + +#define NATIVE_STR(name,nativeName,i) const char *name; \ + size_t name##Len; \ + name = JS_ToCStringLen(ctx, &name##Len, argv[i]); \ + if (!name) return JS_EXCEPTION; \ + char nativeName[ name##Len + 1 ]; \ + memcpy(nativeName, name, name##Len+1); \ + convertToNative(nativeName, (int) name##Len); + + +#endif + +/* + 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. +*/ diff --git a/h/httpclient.h b/h/httpclient.h index fe53d759d..937caa261 100644 --- a/h/httpclient.h +++ b/h/httpclient.h @@ -46,6 +46,7 @@ extern "C" { #define HTTP_CLIENT_READ_ERROR 15 #define HTTP_CLIENT_RESPONSE_ZEROLEN 16 #define HTTP_CLIENT_TLS_ERROR 17 +#define HTTP_CLIENT_TLS_NOT_CONFIGURED 18 typedef struct HttpClientSettings_tag { char *host; diff --git a/h/qjsnet.h b/h/qjsnet.h new file mode 100644 index 000000000..7ffcaeb7f --- /dev/null +++ b/h/qjsnet.h @@ -0,0 +1,32 @@ +/* + 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. +*/ + +#ifndef __ZOWE_QJSNET__ +#define __ZOWE_QJSNET__ 1 + +#include "zowetypes.h" +#include "cutils.h" +#include "quickjs-libc.h" + +int ejsInitNetCallback(JSContext *ctx, JSModuleDef *m); +JSModuleDef *ejsInitModuleNet(JSContext *ctx, const char *module_name); + + +#endif + +/* + 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. +*/ diff --git a/h/qjszos.h b/h/qjszos.h new file mode 100644 index 000000000..f1a40d927 --- /dev/null +++ b/h/qjszos.h @@ -0,0 +1,32 @@ +/* + 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. +*/ + +#ifndef __ZOWE_QJSZOS__ +#define __ZOWE_QJSZOS__ 1 + +#include "zowetypes.h" +#include "cutils.h" +#include "quickjs-libc.h" + +int ejsInitZOSCallback(JSContext *ctx, JSModuleDef *m); +JSModuleDef *ejsInitModuleZOS(JSContext *ctx, const char *module_name); + + +#endif + +/* + 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. +*/ diff --git a/tests/js/net1.js b/tests/js/net1.js new file mode 100644 index 000000000..16ec03294 --- /dev/null +++ b/tests/js/net1.js @@ -0,0 +1,51 @@ +import * as zos from 'zos'; +import * as os from 'os'; +import * as net from 'net'; + +/* + example.com == 93.184.216.34 + + ../bin/configmgr -script ../tests/js/net1.js https 93.184.216.34 443 "/" + ../bin/configmgr -script ../tests/js/net1.js http 93.184.216.34 80 "/" + + ../bin/configmgr -script ../tests/js/net1.js tcp 93.184.216.34 80 + + ../bin/configmgr -script ../tests/js/net1.js tcp 93.184.216.34 800 + + */ + +var testHTTP = function(args, index){ + let scheme = args[index+0]; + let host = args[index+1]; + let port = parseInt(args[index+2]); + let path = args[index+3]; + let [ result, status ] = net.httpContentAsText(scheme,host,port,path); + if (status == 0){ + console.log("content\n"+result); + } else{ + console.log("http client failed with status = "+status); + } +} + +var testTCP = function(args, index){ + let host = args[index+1]; + let port = parseInt(args[index+2]); + let waitMS = parseInt(args[index+3]); + let status = net.tcpPing(host,port,waitMS); + console.log("tcp connect status = "+JSON.stringify(status)); + +} + +var dispatch = function(args, index){ + console.log("Start Net Test "+scriptArgs[3]); + if (scriptArgs[3] == "http" || + scriptArgs[3] == "https" ){ + let configStatus = net.tlsClientConfig({ truststore: "../tests/javatrust.p12", password: "password"}); + console.log("tls config status = "+configStatus); + testHTTP(scriptArgs,3); + } else if (scriptArgs[3] == "tcp"){ + testTCP(scriptArgs,3); + } +} + +dispatch(); diff --git a/tests/js/zos1.js b/tests/js/zos1.js new file mode 100644 index 000000000..ea0c0d32c --- /dev/null +++ b/tests/js/zos1.js @@ -0,0 +1,27 @@ +import * as zos from 'zos'; +import * as os from 'os'; + +var test1 = function(filename){ + let zstats = zos.zstat(filename); + console.log("zosStat => "+JSON.stringify(zstats)); + + console.log("turning on PROGCTL "); + + /* Turning on the PROGCTL Bit */ + zos.changeExtAttr(filename, zos.EXTATTR_PROGCTL, true); + + zstats = zos.zstat(filename); + console.log("zosStat => "+JSON.stringify(zstats)); +} + +var dispatch = function(){ + console.log("Start ZOS Test "+scriptArgs[3]); + if (scriptArgs[3] == "stat"){ + test1(scriptArgs[4]); + } else if (scriptArgs[3] == "dslist"){ + let result = zos.dslist(scriptArgs[4]); + console.log("dslist: "+JSON.stringify(result)); + } +} + +dispatch(); From 6c96392eb3ed1b181b36b3ca48e806c29741def8 Mon Sep 17 00:00:00 2001 From: Joe Devlin Date: Thu, 14 Jul 2022 22:30:36 -0500 Subject: [PATCH 03/28] missing h file from previous push Signed-off-by: Joe Devlin --- h/nativeconversion.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 h/nativeconversion.h diff --git a/h/nativeconversion.h b/h/nativeconversion.h new file mode 100644 index 000000000..5fa9a1e4f --- /dev/null +++ b/h/nativeconversion.h @@ -0,0 +1,42 @@ +/* + 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. +*/ + +#include "zowetypes.h" + +#ifdef __ZOWE_OS_ZOS + +int __atoe_l(char *bufferptr, int leng); +int __etoa_l(char *bufferptr, int leng); + +#endif + +static int convertToNative(char *buf, size_t size) { +#ifdef __ZOWE_OS_ZOS + return __atoe_l(buf, size); +#endif + return 0; +} + +static int convertFromNative(char *buf, size_t size) { +#ifdef __ZOWE_OS_ZOS + return __etoa_l(buf, size); +#endif + return 0; +} + +/* + 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. +*/ From c3aecd2637c8dd8e4951a8102755223e5fa6714f Mon Sep 17 00:00:00 2001 From: Joe Devlin Date: Thu, 21 Jul 2022 14:34:33 -0500 Subject: [PATCH 04/28] object case was shadowing array in jsToJSON Signed-off-by: Joe Devlin --- c/embeddedjs.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/c/embeddedjs.c b/c/embeddedjs.c index 2fb00dab6..1b40fff3e 100644 --- a/c/embeddedjs.c +++ b/c/embeddedjs.c @@ -1470,6 +1470,8 @@ static char *copyToNative(const char *source, ShortLivedHeap *slh){ return dest; } +static char lengthASCII[7] ={0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x00}; + static Json *jsToJson1(EmbeddedJS *ejs, JsonBuilder *b, Json *parent, char *parentKey, JSValue value, @@ -1516,6 +1518,17 @@ static Json *jsToJson1(EmbeddedJS *ejs, } } else if (JS_IsNull(value)){ return jsonBuildNull(b,parent,parentKey,&buildStatus); + } else if (JS_IsArray(ctx,value)){ + Json *jsonArray = jsonBuildArray(b,parent,parentKey,&buildStatus); + JSValue aLenJS = JS_GetPropertyStr(ctx,value,lengthASCII); + int aLen = 0; + buildStatus = JS_ToInt32(ctx,&aLen,aLenJS); + printf("JS array len = %d\n",aLen); + for (int i=0; i Date: Thu, 21 Jul 2022 14:36:33 -0500 Subject: [PATCH 05/28] stray trace Signed-off-by: Joe Devlin --- c/embeddedjs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/c/embeddedjs.c b/c/embeddedjs.c index 1b40fff3e..18a22fb17 100644 --- a/c/embeddedjs.c +++ b/c/embeddedjs.c @@ -1523,7 +1523,6 @@ static Json *jsToJson1(EmbeddedJS *ejs, JSValue aLenJS = JS_GetPropertyStr(ctx,value,lengthASCII); int aLen = 0; buildStatus = JS_ToInt32(ctx,&aLen,aLenJS); - printf("JS array len = %d\n",aLen); for (int i=0; i Date: Fri, 22 Jul 2022 14:27:56 -0400 Subject: [PATCH 06/28] Fix for large allocation on stack during unix file sending causing 0c4 Signed-off-by: 1000TurquoisePogs --- c/httpserver.c | 69 +++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/c/httpserver.c b/c/httpserver.c index f6bb0de31..64de25881 100644 --- a/c/httpserver.c +++ b/c/httpserver.c @@ -3559,15 +3559,15 @@ static int handleHttpService(HttpServer *server, NULL, extractABENDInfo, &abendInfo, NULL, NULL); if (recoveryRC != RC_RCV_OK) { if (recoveryRC == RC_RCV_CONTEXT_NOT_FOUND) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "httpserver: error running service %s, recovery context not found\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_SEVERE, "httpserver: error running service %s, recovery context not found\n", service->name); } else if (recoveryRC == RC_RCV_ABENDED) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "httpserver: ABEND %03X-%02X averted when handling %s\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_SEVERE, "httpserver: ABEND %03X-%02X averted when handling %s\n", abendInfo.completionCode, abendInfo.reasonCode, service->name); } else { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "httpserver: error running service %s unknown recovery code %d\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_SEVERE, "httpserver: error running service %s unknown recovery code %d\n", service->name, recoveryRC); } return handleServiceFailed(conversation, service, response); @@ -4167,7 +4167,7 @@ void respondWithUnixFileContentsWithAutocvtMode (HttpService* service, HttpRespo int reasonCode; int status = fileInfo(absolutePath, &info, &returnCode, &reasonCode); - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "finfo:\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "finfo:\n"); #ifdef DEBUG dumpbuffer((char*)&info, sizeof(FileInfo)); #endif @@ -4305,7 +4305,7 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab if(status == 0) { int filenameLen = strlen(absolutePath); - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Request for file=%s\n",absolutePath); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Request for file=%s\n",absolutePath); int dotPos = lastIndexOf(absolutePath, filenameLen, '.'); int isDotFile = FALSE; if (dotPos > 0 && (absolutePath[dotPos-1] == '/')){ @@ -4316,7 +4316,7 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab long fileSize = fileInfoSize(&info); int ccsid = fileInfoCCSID(&info); char *mimeType = getMimeType2(extension,&isBinary,isDotFile, ccsid); - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "File ccsid=%d, mimetype=%s isBinary=%s\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "File ccsid=%d, mimetype=%s isBinary=%s\n", ccsid,mimeType,isBinary ? "true" : "false"); char tmperr[256] = {0}; time_t mtime = fileInfoUnixModificationTime(&info); @@ -4375,12 +4375,12 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab if (isBinary || ccsid == -1) { writeHeader(response); - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Streaming binary for %s\n", absolutePath); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Streaming binary for %s\n", absolutePath); streamBinaryForFile2(response, NULL, in, ENCODING_CHUNKED, asB64); } else { writeHeader(response); - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Streaming %d for %s\n", ccsid, absolutePath); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Streaming %d for %s\n", ccsid, absolutePath); /* TBD: This isn't really an OS dependency, but this is what I had to do to get this working on Linux. The problem is that there really @@ -4418,7 +4418,7 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab respondWithError(response, HTTP_STATUS_BAD_REQUEST, "source/target encoding value parsing error."); return; } - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Sending with forced conversion between %d and %d\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Sending with forced conversion between %d and %d\n", sscanfSource, sscanfTarget); streamTextForFile2(response, NULL, in, ENCODING_CHUNKED, sEncoding, tEncoding, asB64); } @@ -4428,12 +4428,12 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab } } else if(ccsid == 0) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Sending with default conversion between %d and %d\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Sending with default conversion between %d and %d\n", NATIVE_CODEPAGE, webCodePage); streamTextForFile2(response, NULL, in, ENCODING_CHUNKED, NATIVE_CODEPAGE, webCodePage, asB64); } else { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "Sending with tagged conversion between %d and %d\n", + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Sending with tagged conversion between %d and %d\n", ccsid, webCodePage); streamTextForFile2(response, NULL, in, ENCODING_CHUNKED, ccsid, webCodePage, asB64); } @@ -4449,7 +4449,7 @@ void respondWithUnixFile2(HttpService* service, HttpResponse* response, char* ab finishResponse(response); } else { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "File not found within respondWithUnixFile.. This may be a problem\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "File not found within respondWithUnixFile.. This may be a problem\n"); respondWithUnixFileNotFound(response, jsonMode); // Response is finished on return } @@ -4556,26 +4556,28 @@ void respondWithJsonError(HttpResponse *response, char *error, int statusCode, c static int streamBinaryForFile2(HttpResponse *response, Socket *socket, UnixFile *in, int encoding, bool asB64) { int returnCode = 0; int reasonCode = 0; - int bufferSize = FILE_STREAM_BUFFER_SIZE; - char buffer[bufferSize+4]; - int encodedLength; ChunkedOutputStream *stream = NULL; if ((response && socket) || (!response && !socket)) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "bad arguments: either response or socket must be not NULL, never both\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "bad arguments: either response or socket must be not NULL, never both\n"); return 8; } if (encoding == ENCODING_GZIP) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "GZIP encoding not implemented\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "GZIP encoding not implemented\n"); return 8; } if (encoding == ENCODING_CHUNKED && !response) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "bad arguments: response must be not NULL to use chunked encoding\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "bad arguments: response must be not NULL to use chunked encoding\n"); return 8; } if (encoding == ENCODING_CHUNKED) { stream = makeChunkedOutputStreamInternal(response); } + + int bufferSize = FILE_STREAM_BUFFER_SIZE; + char *buffer = safeMalloc(bufferSize+4, "streamBinaryBuffer"); + int encodedLength; + while (!fileEOF(in)) { int bytesRead = fileRead(in,buffer,bufferSize,&returnCode,&reasonCode); if (bytesRead <= 0) { @@ -4607,6 +4609,8 @@ static int streamBinaryForFile2(HttpResponse *response, Socket *socket, UnixFile finishChunkedOutput(stream, NO_TRANSLATE); } + safeFree(buffer, bufferSize+4); + return 0; } @@ -4623,35 +4627,35 @@ static int streamTextForFile2(HttpResponse *response, Socket *socket, UnixFile * int returnCode = 0; int reasonCode = 0; int bytesSent = 0; - int bufferSize = FILE_STREAM_BUFFER_SIZE; - char buffer[bufferSize+4]; - char translation[(2*bufferSize)+4]; /* UTF inflation tolerance */ - int encodedLength; ChunkedOutputStream *stream = NULL; - /* Q: How do we find character encoding for unix file? A: You can't. There is no equivalent of USS character encoding tags on other Unix systems. Hence, things like the .htaccess (for Apache). */ if ((response && socket) || (!response && !socket)) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "bad arguments: either response or socket must be not NULL, never both\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "bad arguments: either response or socket must be not NULL, never both\n"); return 8; } switch (encoding){ case ENCODING_CHUNKED: if (!response) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "bad arguments: response must be not NULL to use chunked encoding\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "bad arguments: response must be not NULL to use chunked encoding\n"); return 8; } stream = makeChunkedOutputStreamInternal(response); /* fallthrough */ - case ENCODING_SIMPLE: + case ENCODING_SIMPLE: { + int bufferSize = FILE_STREAM_BUFFER_SIZE; + char *buffer = safeMalloc(bufferSize+4, "streamTextBuffer"); + char *translation = safeMalloc((2*bufferSize)+4, "streamTextConvertBuffer"); /* UTF inflation tolerance */ + int encodedLength; + while (!fileEOF(in)){ - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "WARNING: UTF8 might not be aligned properly: preserve 3 bytes for the next read cycle to fix UTF boundaries\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "WARNING: UTF8 might not be aligned properly: preserve 3 bytes for the next read cycle to fix UTF boundaries\n"); int bytesRead = fileRead(in,buffer,bufferSize,&returnCode,&reasonCode); if (bytesRead <= 0) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG2, + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Text streaming has ended. (return = 0x%x, reason = 0x%x)\n", returnCode, reasonCode); break; @@ -4693,7 +4697,7 @@ static int streamTextForFile2(HttpResponse *response, Socket *socket, UnixFile * &reasonCode); if (inLen != translationLength) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "streamTextForFile(%d (%s), %d (%s), %d, %d, %d, %d): " + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "streamTextForFile(%d (%s), %d (%s), %d, %d, %d, %d): " "after sending %d bytes got translation length error; expected %d, got %d\n", getSocketDebugID(socket), socket->debugName, in->fd, in->pathname, @@ -4704,7 +4708,7 @@ static int streamTextForFile2(HttpResponse *response, Socket *socket, UnixFile * dumpbuffer(translation,translationLength); } if (rc != 0){ - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "iconv rc = %d, bytesRead=%d xlateLength=%d\n",rc,bytesRead,translationLength); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "iconv rc = %d, bytesRead=%d xlateLength=%d\n",rc,bytesRead,translationLength); } outPtr = translation; @@ -4714,7 +4718,7 @@ static int streamTextForFile2(HttpResponse *response, Socket *socket, UnixFile * char *encodedBuffer = NULL; if (asB64) { if (outLen % 3) { - zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "buffer length not divisble by 3. Base64Encode will fail if this is not the eof.\n"); + zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "buffer length not divisble by 3. Base64Encode will fail if this is not the eof.\n"); } allocSize = ENCODE64_SIZE(outLen)+1; encodedBuffer = encodeBase64(NULL, outPtr, outLen, &encodedLength, FALSE); @@ -4733,7 +4737,10 @@ static int streamTextForFile2(HttpResponse *response, Socket *socket, UnixFile * /* finish the chunked output here because finishResponse will not flush this stream's data */ finishChunkedOutput(stream, NO_TRANSLATE); } + safeFree(buffer, bufferSize+4); + safeFree(translation, (2*bufferSize)+4); break; + } case ENCODING_GZIP: zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG3, "HELP - not implemented\n"); break; From cac3df54d92768418a8f58baee332ba7f17f07a1 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 28 Jul 2022 17:59:53 +0000 Subject: [PATCH 07/28] Update jsonschema.c Type fix for lht uniqueness Signed-off-by: 1000TurquoisePogs --- c/jsonschema.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/jsonschema.c b/c/jsonschema.c index 1318db11d..8259152d7 100644 --- a/c/jsonschema.c +++ b/c/jsonschema.c @@ -757,7 +757,7 @@ static VResult validateJSONArray(JsonValidator *validator, } } if (valueSpec->uniqueItems){ - long longHash = jsonLongHash(itemValue); + int64_t longHash = jsonLongHash(itemValue); if (lhtGet(uniquenessSet,longHash) != NULL){ addValidityChild(pendingException, makeValidityException(validator, From da512ddb4078885ba230f81005d982b6c706d0d2 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 29 Jul 2022 15:44:57 +0000 Subject: [PATCH 08/28] Update jsonschema.c Signed-off-by: 1000TurquoisePogs --- c/jsonschema.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/c/jsonschema.c b/c/jsonschema.c index 8259152d7..cae952994 100644 --- a/c/jsonschema.c +++ b/c/jsonschema.c @@ -747,6 +747,10 @@ static VResult validateJSONArray(JsonValidator *validator, uniquenessSet = lhtCreate(257,NULL); } + printf("start valueSpec=0x%p\n",valueSpec); + printf("start uniqueItems=%d, uniquenessSet=0x%p\n",valueSpec->uniqueItems, uniquenessSet); + + for (int i=0; iuniqueItems, uniquenessSet); + if (valueSpec->uniqueItems){ + + + int64_t longHash = jsonLongHash(itemValue); + + printf("i=%d, hash=0x%llx, valueSpec=0x%p\n", i, longHash, valueSpec); + printf("i=%d, hash=0x%llx, uniqueItems=%d, uniquenessSet=0x%p\n", i, longHash, valueSpec->uniqueItems, uniquenessSet); + if (lhtGet(uniquenessSet,longHash) != NULL){ addValidityChild(pendingException, makeValidityException(validator, From a0523789c2b1067799b4aa4ae3648df42e1c76b1 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 29 Jul 2022 15:54:56 +0000 Subject: [PATCH 09/28] Update collections.c Signed-off-by: 1000TurquoisePogs --- c/collections.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/c/collections.c b/c/collections.c index ce9a5fb97..3cf727a07 100644 --- a/c/collections.c +++ b/c/collections.c @@ -698,6 +698,9 @@ void *lhtGet(LongHashtable *lht, int64 key){ LongHashEntry *prev = NULL; LongHashEntry* hashentry = lht->backbone[place]; int loopCount = 0; + + printf("hashentry=0x%p, place=%d, lhtbackbone=0x%p\n", hashentry, place, lht->backbone); + dumpbuffer((char*)lht->backbone, 8*lht->backboneSize); if (hashentry != NULL){ while (hashentry != NULL){ From e29866a9573f8cbafa30a0e425f2cc8554e47d03 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 29 Jul 2022 13:58:46 -0400 Subject: [PATCH 10/28] Back to long for testing Signed-off-by: 1000TurquoisePogs --- c/jsonschema.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/jsonschema.c b/c/jsonschema.c index cae952994..49e077de8 100644 --- a/c/jsonschema.c +++ b/c/jsonschema.c @@ -768,7 +768,7 @@ static VResult validateJSONArray(JsonValidator *validator, - int64_t longHash = jsonLongHash(itemValue); + long longHash = jsonLongHash(itemValue); printf("i=%d, hash=0x%llx, valueSpec=0x%p\n", i, longHash, valueSpec); printf("i=%d, hash=0x%llx, uniqueItems=%d, uniquenessSet=0x%p\n", i, longHash, valueSpec->uniqueItems, uniquenessSet); From 13af8f1e9b962f3288007a64e027b93fcfb84d6b Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Fri, 29 Jul 2022 16:27:32 -0400 Subject: [PATCH 11/28] Solution to 0c4, keys must be masked to nonnegative Signed-off-by: 1000TurquoisePogs --- CHANGELOG.md | 4 ++++ c/collections.c | 6 +++--- c/jsonschema.c | 14 +------------- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54bf4cb49..2ab408d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Zowe Common C Changelog +## `2.3.0` + +- Bugfix for lht functions of collections.c to avoid memory issues on negative keys + ## `2.2.0` - Added a script 'dependencies.sh' which assists in managing external depedencies needed for project compilation diff --git a/c/collections.c b/c/collections.c index 3cf727a07..27871a407 100644 --- a/c/collections.c +++ b/c/collections.c @@ -694,13 +694,11 @@ void lhtDestroy(LongHashtable *lht){ } void *lhtGet(LongHashtable *lht, int64 key){ + key = key & 0x7FFFFFFFFFFFFFFFLL; int place = key%(lht->backboneSize); LongHashEntry *prev = NULL; LongHashEntry* hashentry = lht->backbone[place]; int loopCount = 0; - - printf("hashentry=0x%p, place=%d, lhtbackbone=0x%p\n", hashentry, place, lht->backbone); - dumpbuffer((char*)lht->backbone, 8*lht->backboneSize); if (hashentry != NULL){ while (hashentry != NULL){ @@ -728,6 +726,7 @@ void *lhtGet(LongHashtable *lht, int64 key){ /* returns whether replaced */ int lhtPut(LongHashtable *ht, int64 key, void *value){ + key = key & 0x7FFFFFFFFFFFFFFFLL; int place = key%(ht->backboneSize); LongHashEntry *entry = entry = ht->backbone[place]; LongHashEntry *tail = NULL; @@ -762,6 +761,7 @@ int lhtPut(LongHashtable *ht, int64 key, void *value){ /* remove returns non-zero if it really removes anything */ int lhtRemove(LongHashtable *ht, int64 key){ + key = key & 0x7FFFFFFFFFFFFFFFLL; int place = key%(ht->backboneSize); LongHashEntry *prev = NULL; LongHashEntry *entry = entry = ht->backbone[place]; diff --git a/c/jsonschema.c b/c/jsonschema.c index 49e077de8..03d0995ed 100644 --- a/c/jsonschema.c +++ b/c/jsonschema.c @@ -747,9 +747,6 @@ static VResult validateJSONArray(JsonValidator *validator, uniquenessSet = lhtCreate(257,NULL); } - printf("start valueSpec=0x%p\n",valueSpec); - printf("start uniqueItems=%d, uniquenessSet=0x%p\n",valueSpec->uniqueItems, uniquenessSet); - for (int i=0; iuniqueItems, uniquenessSet); - if (valueSpec->uniqueItems){ - - - - long longHash = jsonLongHash(itemValue); - - printf("i=%d, hash=0x%llx, valueSpec=0x%p\n", i, longHash, valueSpec); - printf("i=%d, hash=0x%llx, uniqueItems=%d, uniquenessSet=0x%p\n", i, longHash, valueSpec->uniqueItems, uniquenessSet); + int64_t longHash = jsonLongHash(itemValue); if (lhtGet(uniquenessSet,longHash) != NULL){ addValidityChild(pendingException, From 38e4b155aa5f31049bf7ae4a2630ecd40e442a7b Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Tue, 9 Aug 2022 17:07:09 -0400 Subject: [PATCH 12/28] Bugfix on saving stack when doing csi call Signed-off-by: 1000TurquoisePogs --- c/httpserver.c | 7 +++++++ c/jcsi.c | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/c/httpserver.c b/c/httpserver.c index 64de25881..e658d066a 100644 --- a/c/httpserver.c +++ b/c/httpserver.c @@ -3557,6 +3557,13 @@ static int handleHttpService(HttpServer *server, int recoveryRC = recoveryPush(service->name, RCVR_FLAG_RETRY | RCVR_FLAG_SDWA_TO_LOGREC | RCVR_FLAG_DELETE_ON_RETRY, NULL, extractABENDInfo, &abendInfo, NULL, NULL); + + /* + TODO this function needs a new argument about recording program state at time of abend + Until then, currently recoveryPush will prevent a CEEDUMP + and if you need one, just comment out recoveryPush and recoveryPop + */ + if (recoveryRC != RC_RCV_OK) { if (recoveryRC == RC_RCV_CONTEXT_NOT_FOUND) { zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_SEVERE, "httpserver: error running service %s, recovery context not found\n", diff --git a/c/jcsi.c b/c/jcsi.c index 3fc5a68bf..61b8a2eea 100644 --- a/c/jcsi.c +++ b/c/jcsi.c @@ -68,8 +68,10 @@ static int callCsi(CsiFn *csiFn, void *__ptr32 paramList, char* __ptr32 saveArea __asm( ASM_PREFIX -#ifdef _LP64 +#ifdef __XPLINK__ " L 13,%[saveArea] \n" +#endif +#ifdef _LP64 " SAM31 \n" " SYSSTATE AMODE64=NO \n" #endif From 863d56724da67f6994c9727a05287865b9b349f5 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:17:59 -0400 Subject: [PATCH 13/28] Add a build target for configmgr-rexx Signed-off-by: 1000TurquoisePogs --- .github/workflows/build-configmgr.yml | 2 +- .github/workflows/build-rexxconfigmgr.yml | 89 +++++++++++++++++++++++ .pax/configmgr-rexx/pre-packaging.sh | 37 ++++++++++ .pax/configmgr-rexx/prepare-workspace.sh | 44 +++++++++++ CHANGELOG.md | 1 + 5 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/build-rexxconfigmgr.yml create mode 100755 .pax/configmgr-rexx/pre-packaging.sh create mode 100755 .pax/configmgr-rexx/prepare-workspace.sh diff --git a/.github/workflows/build-configmgr.yml b/.github/workflows/build-configmgr.yml index 612db349d..bc3362cc3 100644 --- a/.github/workflows/build-configmgr.yml +++ b/.github/workflows/build-configmgr.yml @@ -1,4 +1,4 @@ -name: Build and Test Workflow +name: Build configmgr on: push: branches: diff --git a/.github/workflows/build-rexxconfigmgr.yml b/.github/workflows/build-rexxconfigmgr.yml new file mode 100644 index 000000000..3a56da0f8 --- /dev/null +++ b/.github/workflows/build-rexxconfigmgr.yml @@ -0,0 +1,89 @@ +name: Build REXX configmgr +on: + push: + branches: + - v2.x/staging + - v2.x/master + - v2.x/rc + pull_request: + types: [opened, reopened, synchronize] + workflow_dispatch: + inputs: + PERFORM_RELEASE: + description: '[Release] perform release' + required: false + default: 'false' + + +jobs: + check-permission: + runs-on: ubuntu-latest + steps: + # this action will fail the whole workflow if permission check fails + - name: check permission + uses: zowe-actions/shared-actions/permission-check@main + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + + build-test: + runs-on: ubuntu-latest + needs: check-permission + steps: + - name: '[Prep 1] Checkout' + uses: actions/checkout@v2 + + - name: '[Dep 1] Libyaml' + uses: actions/checkout@v3 + with: + repository: yaml/libyaml + path: deps/configmgr/libyaml + ref: '0.2.5' + + - name: '[Dep 2] Quickjs' + uses: actions/checkout@v3 + with: + repository: joenemo/quickjs-portable + path: deps/configmgr/quickjs + ref: 'main' + + - name: '[Prep 2] Setup jFrog CLI' + uses: jfrog/setup-jfrog-cli@v2 + env: + JF_ARTIFACTORY_1: ${{ secrets.JF_ARTIFACTORY_TOKEN }} + + - name: '[Prep 3] Set date' + id: date + run: echo "::set-output name=date::$(date +'%Y%m%d%S')" + + - name: '[Prep 4] Set version' + id: version + run: echo "::set-output name=version::$(cat build/configmgr.proj.env | grep VERSION | cut -f 2 -d=)" + + - name: '[Prep 5] Set branchname' + id: branch + run: echo "::set-output name=branch::$(if [ -n '${{ github.head_ref }}' ]; then echo '${{ github.head_ref }}'; else echo '${{ github.ref_name }}'; fi | sed 's@/@_@g')" + + + - name: '[Prep 6] Prepare workflow' + uses: zowe-actions/shared-actions/prepare-workflow@main + + + - name: '[Packaging] Make pax' + uses: zowe-actions/shared-actions/make-pax@main + with: + pax-name: 'configmgr_rexx' + pax-options: '-x os390 -pp' + pax-local-workspace: './.pax/configmgr-rexx' + pax-ssh-username: ${{ secrets.SSH_MARIST_USERNAME }} + pax-ssh-password: ${{ secrets.SSH_MARIST_RACF_PASSWORD }} + + - name: '[Publish] Publish' + uses: zowe-actions/shared-actions/publish@main + if: success() + with: + artifacts: | + .pax/configmgr/configmgr.pax + publish-target-path-pattern: libs-snapshot-local/org/zowe/configmgr-rexx/${{ steps.version.outputs.version }}-${{ steps.branch.outputs.branch }} + publish-target-file-pattern: configmgr_rexx-${{ steps.version.outputs.version }}-${{ steps.date.outputs.date }}.pax + perform-release: ${{ github.event.inputs.PERFORM_RELEASE }} + diff --git a/.pax/configmgr-rexx/pre-packaging.sh b/.pax/configmgr-rexx/pre-packaging.sh new file mode 100755 index 000000000..919b965e0 --- /dev/null +++ b/.pax/configmgr-rexx/pre-packaging.sh @@ -0,0 +1,37 @@ +#!/bin/sh -e +set -xe + +################################################################################ +# 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. +################################################################################ + + +# contants +SCRIPT_NAME=$(basename "$0") +SCRIPT_DIR=$(pwd) + +# build +echo "$SCRIPT_NAME build_rexxcmgr.sh ..." +STEPLIB=CBC.SCCNCMP "$SCRIPT_DIR/content/build/build_rexxcmgr.sh" + +echo "$SCRIPT_NAME build_rexxintfsh ..." +STEPLIB=CBC.SCCNCMP "$SCRIPT_DIR/content/build/build_rexxintf.sh" + + +# clean up content folder +echo "$SCRIPT_NAME cleaning up pax folder ..." +cd "$SCRIPT_DIR" +mv content bak && mkdir -p content + +# move real files to the content folder +echo "$SCRIPT_NAME coping files should be in pax ..." +cd "$SCRIPT_DIR/content" +cp ../bak/bin/zwecfg31 . +cp ../bak/bin/zwecfg64 . +cp ../bak/bin/zwecfgle . diff --git a/.pax/configmgr-rexx/prepare-workspace.sh b/.pax/configmgr-rexx/prepare-workspace.sh new file mode 100755 index 000000000..16ca6a6a6 --- /dev/null +++ b/.pax/configmgr-rexx/prepare-workspace.sh @@ -0,0 +1,44 @@ +#!/bin/sh -e +set -xe + +################################################################################ +# 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. +################################################################################ + +################################################################################ +# Prepare folders/files will be uploaded to Build/PAX server +################################################################################ + +# contants +SCRIPT_NAME=$(basename "$0") +SCRIPT_DIR=$(dirname "$0") +PAX_WORKSPACE_DIR=.pax/configmgr-rexx + +# make sure in project root folder +cd $SCRIPT_DIR/../.. + +# prepare pax workspace +echo "[${SCRIPT_NAME}] preparing folders ..." +rm -fr "${PAX_WORKSPACE_DIR}/ascii" && mkdir -p "${PAX_WORKSPACE_DIR}/ascii" +rm -fr "${PAX_WORKSPACE_DIR}/content" && mkdir -p "${PAX_WORKSPACE_DIR}/content" + +echo "[${SCRIPT_NAME}] copying files ..." +cp -R * "${PAX_WORKSPACE_DIR}/ascii" +# move files shouldn't change encoding to IBM-1047 to content folder +rsync -rv \ + --include '*/' \ + --include '*.png' \ + --exclude '*' \ + --prune-empty-dirs --remove-source-files \ + "${PAX_WORKSPACE_DIR}/ascii/" \ + "${PAX_WORKSPACE_DIR}/content/" + +# update build information +# BRANCH_NAME and BUILD_NUMBER is Jenkins environment variable +commit_hash=$(git rev-parse --verify HEAD) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ab408d71..e30bc943f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## `2.3.0` - Bugfix for lht functions of collections.c to avoid memory issues on negative keys +- Added a new build target, 'configmgr-rexx', which builds a version of configmgr that can be used within rexx scripts. ## `2.2.0` From b0e3e500f68dc9ffd33efb494f2c2103436ab466 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:23:34 -0400 Subject: [PATCH 14/28] Updating build script for new files Signed-off-by: 1000TurquoisePogs --- build/build_rexxcmgr.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index 991447639..72ba0a9ef 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -139,6 +139,8 @@ xlc \ ${COMMON}/c/microjq.c \ ${COMMON}/c/parsetools.c \ ${COMMON}/c/pdsutil.c \ + ${COMMON}/c/qjsnet.c \ + ${COMMON}/c/qjszos.c \ ${COMMON}/platform/posix/psxregex.c \ ${COMMON}/c/recovery.c \ ${COMMON}/c/rexxcmgr.c \ From 747bcf196a672fadcf08253aaacbffcb0591ccf6 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:30:18 -0400 Subject: [PATCH 15/28] Updating build script for new files Signed-off-by: 1000TurquoisePogs --- build/build_rexxcmgr.sh | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index 72ba0a9ef..b8af793eb 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -39,6 +39,9 @@ MINOR=2 PATCH=5 VERSION="\"${MAJOR}.${MINOR}.${PATCH}\"" +GSKDIR=/usr/lpp/gskssl +GSKINC="${GSKDIR}/include" + xlclang \ -c \ -q64 \ @@ -106,9 +109,12 @@ xlc \ -D_XOPEN_SOURCE=600 \ -D_OPEN_THREADS=1 \ -DNEW_CAA_LOCATIONS=1 \ + -DUSE_ZOWE_TLS=1 \ -I "${COMMON}/h" \ -I "${COMMON}/platform/posix" \ + -I ${GSKINC} \ -I "${DEPS_DESTINATION}/${LIBYAML}/include" \ + -I "${DEPS_DESTINATION}/${QUICKJS}" \ -o "${COMMON}/bin/zwecfgle" \ api.o \ reader.o \ @@ -132,7 +138,12 @@ xlc \ ${COMMON}/c/charsets.c \ ${COMMON}/c/collections.c \ ${COMMON}/c/configmgr.c \ + ${COMMON}/c/embeddedjs.c \ + ${COMMON}/c/fdpoll.c \ + ${COMMON}/c/http.c \ + ${COMMON}/c/httpclient.c \ ${COMMON}/c/json.c \ + ${COMMON}/c/jcsi.c \ ${COMMON}/c/jsonschema.c \ ${COMMON}/c/le.c \ ${COMMON}/c/logging.c \ @@ -145,12 +156,17 @@ xlc \ ${COMMON}/c/recovery.c \ ${COMMON}/c/rexxcmgr.c \ ${COMMON}/c/scheduling.c \ + ${COMMON}/c/socketmgmt.c \ ${COMMON}/c/timeutls.c \ + ${COMMON}/c/tls.c \ ${COMMON}/c/utils.c \ ${COMMON}/c/xlate.c \ ${COMMON}/c/yaml2json.c \ ${COMMON}/c/zos.c \ - ${COMMON}/c/zosfile.c + ${COMMON}/c/zosfile.c \ + ${GSKDIR}/lib/GSKSSL64.x \ + ${GSKDIR}/lib/GSKCMS64.x + #then # echo "Build successful" # ls -l "${COMMON}/bin" From 9569823030b4a7afe33384d5348954c8f5f5ee28 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:36:56 -0400 Subject: [PATCH 16/28] missing xlclang ref Signed-off-by: 1000TurquoisePogs --- build/build_rexxcmgr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index b8af793eb..908f7898e 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -102,7 +102,7 @@ xlclang \ # Hacking around weird link issue: ar x /usr/lpp/cbclib/lib/libibmcmp.a z_atomic.LIB64R.o -xlc \ +xlclang \ -q64 \ "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN'),list()" \ -D_OPEN_SYS_FILE_EXT=1 \ From eedd0d65f62a1cc08b6d4edbcd7e79f365769e26 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:43:28 -0400 Subject: [PATCH 17/28] Use COMMON substitution for relative paths in build Signed-off-by: 1000TurquoisePogs --- build/build_rexxintf.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/build/build_rexxintf.sh b/build/build_rexxintf.sh index 1ed614b89..7fc5167ca 100755 --- a/build/build_rexxintf.sh +++ b/build/build_rexxintf.sh @@ -1,12 +1,19 @@ #! /bin/sh +WORKING_DIR=$(dirname "$0") + +echo "********************************************************************************" +echo "Building configmgr INTF for REXX" + +COMMON="$WORKING_DIR/.." + # Step 0 Libraries export _LD_SYSLIB="//'SYS1.CSSLIB'://'CEE.SCEELKEX'://'CEE.SCEELKED'://'CEE.SCEERUN'://'CEE.SCEERUN2'://'CSF.SCSFMOD0'://'CBC.SCCNOBJ'" # Step 1: Build 31-bit program for REXX -xlc -qmetal -DMSGPREFIX=\"JOE\" -DSUBPOOL=132 -DMETTLE=1 "-Wc,longname,langlvl(extc99),goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -I ../h -S ../c/zwecfg31.c ../c/metalio.c ../c/zos.c ../c/qsam.c ../c/timeutls.c ../c/utils.c ../c/alloc.c +xlc -qmetal -DMSGPREFIX=\"ZWE\" -DSUBPOOL=132 -DMETTLE=1 "-Wc,longname,langlvl(extc99),goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -I ${COMMON}/h -S ${COMMON}/c/zwecfg31.c ${COMMON}/c/metalio.c ${COMMON}/c/zos.c ${COMMON}/c/qsam.c ${COMMON}/c/timeutls.c ${COMMON}/c/utils.c ${COMMON}/c/alloc.c as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zwecfg31.asm zwecfg31.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm alloc.s @@ -16,11 +23,11 @@ as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm zos.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm qsam.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm metalio.s -ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ../bin/zwecfg31 zwecfg31.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o +ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/zwecfg31 zwecfg31.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o # Step 2: Build 64 Bit Metal program to be called from REXX to call LE64 -xlc -qmetal -q64 -DMSGPREFIX=\"JOE\" -DMETAL_PRINTF_TO_STDOUT=1 -DSUBPOOL=132 -DMETTLE=1 "-Wc,longname,langlvl(extc99),goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -I ../h -S ../c/rex2le64.c ../c/metalio.c ../c/zos.c ../c/qsam.c ../c/timeutls.c ../c/utils.c ../c/alloc.c +xlc -qmetal -q64 -DMSGPREFIX=\"ZWE\" -DMETAL_PRINTF_TO_STDOUT=1 -DSUBPOOL=132 -DMETTLE=1 "-Wc,longname,langlvl(extc99),goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" -I ${COMMON}/h -S ${COMMON}/c/rex2le64.c ${COMMON}/c/metalio.c ${COMMON}/c/zos.c ${COMMON}/c/qsam.c ${COMMON}/c/timeutls.c ${COMMON}/c/utils.c ${COMMON}/c/alloc.c as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=rexle64.asm rex2le64.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=alloc.asm alloc.s @@ -30,5 +37,5 @@ as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm zos.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm qsam.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm metalio.s -ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ../bin/zwecfg64 rex2le64.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o +ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/zwecfg64 rex2le64.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o From 75dda20e94ec462b6d85f636313fe3354c1c7bc0 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:46:59 -0400 Subject: [PATCH 18/28] Fix pax name Signed-off-by: 1000TurquoisePogs --- .github/workflows/build-rexxconfigmgr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-rexxconfigmgr.yml b/.github/workflows/build-rexxconfigmgr.yml index 3a56da0f8..0d1d04526 100644 --- a/.github/workflows/build-rexxconfigmgr.yml +++ b/.github/workflows/build-rexxconfigmgr.yml @@ -82,7 +82,7 @@ jobs: if: success() with: artifacts: | - .pax/configmgr/configmgr.pax + .pax/configmgr-rexx/configmgr_rexx.pax publish-target-path-pattern: libs-snapshot-local/org/zowe/configmgr-rexx/${{ steps.version.outputs.version }}-${{ steps.branch.outputs.branch }} publish-target-file-pattern: configmgr_rexx-${{ steps.version.outputs.version }}-${{ steps.date.outputs.date }}.pax perform-release: ${{ github.event.inputs.PERFORM_RELEASE }} From 42965b3f92a27e96a899d8d5de75e8d45bfa81b4 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 15 Aug 2022 17:51:34 -0400 Subject: [PATCH 19/28] Fix pax name Signed-off-by: 1000TurquoisePogs --- .github/workflows/build-rexxconfigmgr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-rexxconfigmgr.yml b/.github/workflows/build-rexxconfigmgr.yml index 0d1d04526..b6fb60ff8 100644 --- a/.github/workflows/build-rexxconfigmgr.yml +++ b/.github/workflows/build-rexxconfigmgr.yml @@ -71,7 +71,7 @@ jobs: - name: '[Packaging] Make pax' uses: zowe-actions/shared-actions/make-pax@main with: - pax-name: 'configmgr_rexx' + pax-name: 'configmgr-rexx' pax-options: '-x os390 -pp' pax-local-workspace: './.pax/configmgr-rexx' pax-ssh-username: ${{ secrets.SSH_MARIST_USERNAME }} @@ -82,7 +82,7 @@ jobs: if: success() with: artifacts: | - .pax/configmgr-rexx/configmgr_rexx.pax + .pax/configmgr-rexx/configmgr-rexx.pax publish-target-path-pattern: libs-snapshot-local/org/zowe/configmgr-rexx/${{ steps.version.outputs.version }}-${{ steps.branch.outputs.branch }} publish-target-file-pattern: configmgr_rexx-${{ steps.version.outputs.version }}-${{ steps.date.outputs.date }}.pax perform-release: ${{ github.event.inputs.PERFORM_RELEASE }} From 6ee25d3f0c5c96aeb82054db7bf9ffb6c0380235 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 29 Aug 2022 16:07:48 -0400 Subject: [PATCH 20/28] Make the configmgr output uppercase so it fits into a dataset easier Signed-off-by: 1000TurquoisePogs --- build/build_rexxcmgr.sh | 2 +- build/build_rexxintf.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index 908f7898e..380acd44c 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -115,7 +115,7 @@ xlclang \ -I ${GSKINC} \ -I "${DEPS_DESTINATION}/${LIBYAML}/include" \ -I "${DEPS_DESTINATION}/${QUICKJS}" \ - -o "${COMMON}/bin/zwecfgle" \ + -o "${COMMON}/bin/ZWECFGLE" \ api.o \ reader.o \ scanner.o \ diff --git a/build/build_rexxintf.sh b/build/build_rexxintf.sh index 7fc5167ca..b0541de61 100755 --- a/build/build_rexxintf.sh +++ b/build/build_rexxintf.sh @@ -23,7 +23,7 @@ as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm zos.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm qsam.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm metalio.s -ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/zwecfg31 zwecfg31.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o +ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/ZWECFG31 zwecfg31.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o # Step 2: Build 64 Bit Metal program to be called from REXX to call LE64 @@ -37,5 +37,5 @@ as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=zos.asm zos.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=qsam.asm qsam.s as -mgoff -mobject -mflag=nocont --TERM --RENT -aegimrsx=metalio.asm metalio.s -ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/zwecfg64 rex2le64.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o +ld -b rent -b case=mixed -b map -b xref -b reus -e main -o ${COMMON}/bin/ZWECFG64 rex2le64.o metalio.o qsam.o zos.o timeutls.o utils.o alloc.o From ff683c638d1a25b24ed9e07be93245436666673a Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Mon, 29 Aug 2022 16:14:01 -0400 Subject: [PATCH 21/28] Fix casing on prepackaging Signed-off-by: 1000TurquoisePogs --- .pax/configmgr-rexx/pre-packaging.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.pax/configmgr-rexx/pre-packaging.sh b/.pax/configmgr-rexx/pre-packaging.sh index 919b965e0..da284d0ff 100755 --- a/.pax/configmgr-rexx/pre-packaging.sh +++ b/.pax/configmgr-rexx/pre-packaging.sh @@ -32,6 +32,6 @@ mv content bak && mkdir -p content # move real files to the content folder echo "$SCRIPT_NAME coping files should be in pax ..." cd "$SCRIPT_DIR/content" -cp ../bak/bin/zwecfg31 . -cp ../bak/bin/zwecfg64 . -cp ../bak/bin/zwecfgle . +cp ../bak/bin/ZWECFG31 . +cp ../bak/bin/ZWECFG64 . +cp ../bak/bin/ZWECFGLE . From b0a8e6977b6b92599416a1106f6a895abfd729bc Mon Sep 17 00:00:00 2001 From: Jordan Filteau Date: Mon, 29 Aug 2022 22:21:08 -0400 Subject: [PATCH 22/28] hiding printf behind traceLevel; fixing build for cfgmgr-rexx; optionally print validity exceptions Signed-off-by: Jordan Filteau --- build/build_rexxcmgr.sh | 34 ++++++++++++++++++---------------- build/deploy_rexxcmgr.sh | 6 +++--- c/rexxcmgr.c | 25 +++++++++++++++++++++---- c/zwecfg31.c | 25 +++++++++++++++++-------- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index 380acd44c..938c9441b 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -39,9 +39,6 @@ MINOR=2 PATCH=5 VERSION="\"${MAJOR}.${MINOR}.${PATCH}\"" -GSKDIR=/usr/lpp/gskssl -GSKINC="${GSKDIR}/include" - xlclang \ -c \ -q64 \ @@ -93,16 +90,22 @@ xlclang \ -D_OPEN_SYS_FILE_EXT=1 \ -D_XOPEN_SOURCE=600 \ -D_OPEN_THREADS=1 \ + -DUSE_ZOWE_TLS=1 \ -DCONFIG_VERSION=\"2021-03-27\" \ -I "${DEPS_DESTINATION}/${LIBYAML}/include" \ -I "${DEPS_DESTINATION}/${QUICKJS}" \ -I ${COMMON}/h \ - ${COMMON}/c/embeddedjs.c + ${COMMON}/c/embeddedjs.c \ + ${COMMON}/c/qjszos.c \ + ${COMMON}/c/qjsnet.c # Hacking around weird link issue: ar x /usr/lpp/cbclib/lib/libibmcmp.a z_atomic.LIB64R.o -xlclang \ +GSKDIR=/usr/lpp/gskssl +GSKINC="${GSKDIR}/include" + +xlc \ -q64 \ "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN'),list()" \ -D_OPEN_SYS_FILE_EXT=1 \ @@ -132,47 +135,45 @@ xlclang \ polyfill.o \ debugutil.o \ embeddedjs.o \ + qjszos.o \ + qjsnet.o \ z_atomic.LIB64R.o \ ${COMMON}/c/alloc.c \ ${COMMON}/c/bpxskt.c \ ${COMMON}/c/charsets.c \ ${COMMON}/c/collections.c \ ${COMMON}/c/configmgr.c \ - ${COMMON}/c/embeddedjs.c \ - ${COMMON}/c/fdpoll.c \ - ${COMMON}/c/http.c \ - ${COMMON}/c/httpclient.c \ ${COMMON}/c/json.c \ - ${COMMON}/c/jcsi.c \ ${COMMON}/c/jsonschema.c \ ${COMMON}/c/le.c \ ${COMMON}/c/logging.c \ ${COMMON}/c/microjq.c \ ${COMMON}/c/parsetools.c \ ${COMMON}/c/pdsutil.c \ - ${COMMON}/c/qjsnet.c \ - ${COMMON}/c/qjszos.c \ ${COMMON}/platform/posix/psxregex.c \ ${COMMON}/c/recovery.c \ ${COMMON}/c/rexxcmgr.c \ ${COMMON}/c/scheduling.c \ - ${COMMON}/c/socketmgmt.c \ ${COMMON}/c/timeutls.c \ - ${COMMON}/c/tls.c \ ${COMMON}/c/utils.c \ ${COMMON}/c/xlate.c \ ${COMMON}/c/yaml2json.c \ ${COMMON}/c/zos.c \ ${COMMON}/c/zosfile.c \ + ${COMMON}/c/httpclient.c \ + ${COMMON}/c/http.c \ + ${COMMON}/c/tls.c \ + ${COMMON}/c/socketmgmt.c \ + ${COMMON}/c/fdpoll.c \ + ${COMMON}/c/jcsi.c \ ${GSKDIR}/lib/GSKSSL64.x \ ${GSKDIR}/lib/GSKCMS64.x - #then # echo "Build successful" # ls -l "${COMMON}/bin" # exit 0 #else -# # remove configmgr in case the linker had RC=4 and produced the binary + # remove configmgr in case the linker had RC=4 and produced the binary # rm -f "${COMMON}/bin/configmgr" # echo "Build failed" # exit 8 @@ -186,3 +187,4 @@ xlclang \ # SPDX-License-Identifier: EPL-2.0 # # Copyright Contributors to the Zowe Project. + diff --git a/build/deploy_rexxcmgr.sh b/build/deploy_rexxcmgr.sh index 1ea932c64..3620106ce 100755 --- a/build/deploy_rexxcmgr.sh +++ b/build/deploy_rexxcmgr.sh @@ -1,9 +1,9 @@ #! /bin/sh if [ "$#" -eq 1 ] then - cp ../bin/zwecfg31 "//'$1(ZWECFG31)'" - cp ../bin/zwecfg64 "//'$1(ZWECFG64)'" - cp ../bin/zwecfgle "//'$1(ZWERXCFG)'" + cp ../bin/ZWECFG31 "//'$1(ZWECFG31)'" + cp ../bin/ZWECFG64 "//'$1(ZWECFG64)'" + cp ../bin/ZWECFGLE "//'$1(ZWERXCFG)'" else echo "Bad arguments" fi diff --git a/c/rexxcmgr.c b/c/rexxcmgr.c index 6e47d389f..ae2a6a0b7 100644 --- a/c/rexxcmgr.c +++ b/c/rexxcmgr.c @@ -205,7 +205,9 @@ static void writeJSONToREXX1(EXCOMContext *context, Json *json, int varLength, fprintf(out,"*** PANIC *** unknown JSON type %d\n",json->type); break; } - fprintf(out,"back from write REXX\n"); + if (context->mgr->traceLevel >= 1){ + fprintf(out,"back from write REXX\n"); + } } static void writeJSONToREXX(REXXInvocation *invocation, ConfigManager *mgr, Json *json, char *stem, char *separator){ @@ -216,6 +218,18 @@ static void writeJSONToREXX(REXXInvocation *invocation, ConfigManager *mgr, Json freeEXCOMContext(context); } +static void traceValidityException(ConfigManager *mgr, int depth, ValidityException *exception){ + for (int i=0; itraceOut," "); + } + fprintf(mgr->traceOut,"%s\n",exception->message); + ValidityException *child = exception->firstChild; + while (child){ + traceValidityException(mgr,depth+1,child); + child = child->nextSibling; + } +} + static void copyValidityException(EXCOMContext *context, ValidityException *exception, int depth, int varLength){ int messageLen = strlen(exception->message); int extendedVarLength = snprintf(context->varName+varLength,MAX_VAR-varLength,"%s%dmessage", @@ -341,7 +355,11 @@ static int rexxValidate(ConfigManager *mgr, int validateStatus = cfgValidate(mgr,validator,configName); fprintf(mgr->traceOut,"validateStatus=%d\n",validateStatus); if (validateStatus == JSON_VALIDATOR_HAS_EXCEPTIONS){ - writeValidityExceptionToRexx(invocation,mgr,validator->topValidityException,stem); + if (!strcmp(stem, "STDOUT")) { + traceValidityException(mgr,0,validator->topValidityException); + } else { + writeValidityExceptionToRexx(invocation,mgr,validator->topValidityException,stem); + } } else if (validateStatus == JSON_VALIDATOR_INTERNAL_FAILURE){ fprintf(mgr->traceOut,"validation internal failure: %s",validator->errorMessage); } @@ -405,7 +423,6 @@ static int rexxEntry(ConfigManager *mgr, REXXInvocation *invocation){ if (!strcmp(arg0,"setTraceLevel")){ status = rexxSetTraceLevel(mgr,invocation,invocation->argCount,copiedArgs); } else if (!strcmp(arg0,"addConfig")){ - fprintf(out,"rexxcmgr chose addConfig\n"); status = rexxAddConfig(mgr,invocation,invocation->argCount,copiedArgs); } else if (!strcmp(arg0,"setConfigPath")){ status = rexxSetConfigPath(mgr,invocation,invocation->argCount,copiedArgs); @@ -440,7 +457,7 @@ int REXXCMGR(REXXInvocation *invocation){ if (invocation->traceLevel >= 1){ printf("configmgr made at 0x%p\n",theConfigManager); } - theConfigManager->traceOut = fopen("/u/zossteam/jdevlin/git2022/zss/deps/zowe-common-c/tests/rexxcmgr.txt","w"); + theConfigManager->traceOut = fopen("//dd:cmgrout","w"); } FILE *out = theConfigManager->traceOut; if (invocation->traceLevel >= 1){ diff --git a/c/zwecfg31.c b/c/zwecfg31.c index 6d701295a..3793e41b5 100644 --- a/c/zwecfg31.c +++ b/c/zwecfg31.c @@ -89,26 +89,33 @@ static REXXEnv *getOrMakeREXXEnv(IRXENVB *envBlock){ printf("Start making REXX ENV\n"); } int loadStatus = 0; - printf("JOE.0\n"); - int initEP = (int)loadByName("ZWECFG64",&loadStatus); - printf("loadByName ep=0x%x\n",initEP); + int initEP = (int)loadByName("ZWECFG64",&loadStatus); + if (traceLevel >= 1) { + printf("loadByName ep=0x%x\n",initEP); + } if (initEP == 0 || loadStatus){ printf("Failed to load 'ZWECFG64', status=%d\n",loadStatus); return NULL; } else{ - printf("initEP=0x%p\n",initEP); + if (traceLevel >= 1) { + printf("initEP=0x%p\n",initEP); + } initEP &= 0x7FFFFFFE; /* remove DOO-DOO */ } loadStatus = 0; - printf("before second load\n"); + if (traceLevel >= 1) { + printf("before second load\n"); + } int irxexcomEP = (int)loadByName("IRXEXCOM",&loadStatus); - printf("after second load, status=%d\n"); + if (traceLevel >= 1) { + printf("after second load, status=%d\n",loadStatus); + } if (irxexcomEP == 0 || loadStatus){ printf("Failed to load 'IRXEXCOM', status=%d\n",loadStatus); return NULL; } else{ if (traceLevel >= 1){ - printf("irxexcomEP=0x%p\n",irxexcomEP); + printf("irxexcomEP=0x%p\n",irxexcomEP); } irxexcomEP &= 0x7FFFFFFE; /* remove DOO-DOO */ } @@ -256,7 +263,9 @@ int main(int argc, char *argv){ :"=m"(r0),"=m"(r1) ::"r8"); Addr31 envBlock = (Addr31)r0; - printf("ZWECFG31 REXX Call Start\n"); + if (traceLevel >= 1) { + printf("ZWECFG31 REXX Call Start\n"); + } IRXEFPL *efpl = (IRXEFPL*)INT2PTR(r1); if (traceLevel >= 1){ printf("EFPL at 0x%p, r1 = 0x%x\n",efpl,r1); From 9281936328dc3ef82bf655d176f0d9cb8cf1f0e0 Mon Sep 17 00:00:00 2001 From: Jordan Filteau Date: Tue, 30 Aug 2022 18:12:18 -0400 Subject: [PATCH 23/28] fixing bad regex Signed-off-by: Jordan Filteau --- c/configmgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/configmgr.c b/c/configmgr.c index b0f2b7328..6e3c64171 100644 --- a/c/configmgr.c +++ b/c/configmgr.c @@ -429,7 +429,7 @@ static bool addPathElement(ConfigManager *mgr, CFGConfig *config, char *pathElem regmatch_t matches[10]; regex_t *argPattern = regexAlloc(); /* Nice Regex test site */ - char *pat = "^(LIBRARY|DIR|FILE|PARMLIBS)\\(([^)]+)\\)$"; + char *pat = "^(LIBRARY|DIR|FILE|PARMLIBS|PARMLIB)\\(([^)]+)\\)$"; int compStatus = regexComp(argPattern,pat,REG_EXTENDED); if (compStatus != 0){ From 536bc033cf92458f464a036872b59cf487990d7b Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 31 Aug 2022 14:43:38 -0400 Subject: [PATCH 24/28] Rename rexx exec Signed-off-by: 1000TurquoisePogs --- build/build_rexxcmgr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/build_rexxcmgr.sh b/build/build_rexxcmgr.sh index 938c9441b..4604f8778 100755 --- a/build/build_rexxcmgr.sh +++ b/build/build_rexxcmgr.sh @@ -118,7 +118,7 @@ xlc \ -I ${GSKINC} \ -I "${DEPS_DESTINATION}/${LIBYAML}/include" \ -I "${DEPS_DESTINATION}/${QUICKJS}" \ - -o "${COMMON}/bin/ZWECFGLE" \ + -o "${COMMON}/bin/ZWERXCFG" \ api.o \ reader.o \ scanner.o \ From f26482d10fdad4493959c951a1f2bd76b864a7d6 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 31 Aug 2022 14:44:19 -0400 Subject: [PATCH 25/28] Rename rexx exec Signed-off-by: 1000TurquoisePogs --- build/deploy_rexxcmgr.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/deploy_rexxcmgr.sh b/build/deploy_rexxcmgr.sh index 3620106ce..011903273 100755 --- a/build/deploy_rexxcmgr.sh +++ b/build/deploy_rexxcmgr.sh @@ -3,7 +3,7 @@ if [ "$#" -eq 1 ] then cp ../bin/ZWECFG31 "//'$1(ZWECFG31)'" cp ../bin/ZWECFG64 "//'$1(ZWECFG64)'" - cp ../bin/ZWECFGLE "//'$1(ZWERXCFG)'" + cp ../bin/ZWERXCFG "//'$1(ZWERXCFG)'" else echo "Bad arguments" fi From 205b682eb247eb233b669eaedfc36cb404c98148 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Wed, 31 Aug 2022 14:48:22 -0400 Subject: [PATCH 26/28] Rename rexx exec Signed-off-by: 1000TurquoisePogs --- .pax/configmgr-rexx/pre-packaging.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pax/configmgr-rexx/pre-packaging.sh b/.pax/configmgr-rexx/pre-packaging.sh index da284d0ff..c89dff5da 100755 --- a/.pax/configmgr-rexx/pre-packaging.sh +++ b/.pax/configmgr-rexx/pre-packaging.sh @@ -34,4 +34,4 @@ echo "$SCRIPT_NAME coping files should be in pax ..." cd "$SCRIPT_DIR/content" cp ../bak/bin/ZWECFG31 . cp ../bak/bin/ZWECFG64 . -cp ../bak/bin/ZWECFGLE . +cp ../bak/bin/ZWERXCFG . From 80889a72cde0b2c035d6a2bfb83eedcace69bed9 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 1 Sep 2022 15:17:09 -0400 Subject: [PATCH 27/28] Fix printout for configmgr use Signed-off-by: 1000TurquoisePogs --- c/configmgr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/c/configmgr.c b/c/configmgr.c index 6e3c64171..0fd9ed130 100644 --- a/c/configmgr.c +++ b/c/configmgr.c @@ -1223,13 +1223,14 @@ static void showHelp(FILE *out){ fprintf(out," -w : workspace directory\n"); fprintf(out," -c : compact output for jq and extract commands\n"); fprintf(out," -r : raw string output for jq and extract commands\n"); + fprintf(out," -m : member name to find the zowe config in each PARMLIBs specified\n"); fprintf(out," -p : list of colon-separated configPathElements - see below\n"); fprintf(out," commands:\n"); fprintf(out," extract : prints value to stdout\n"); fprintf(out," validate : just loads and validates merged configuration\n"); fprintf(out," env : prints merged configuration to a file as a list of environment vars\n"); fprintf(out," configPathElement: \n"); - fprintf(out," LIB(datasetName) - a library that can contain config data\n"); + fprintf(out," PARMLIB(datasetName) - a library that can contain config data\n"); fprintf(out," FILE(filename) - the name of a file containing Yaml\n"); fprintf(out," PARMLIBS - all PARMLIBS that are defined to this running Program in ZOS, nothing if not on ZOS\n"); } From f096691cd198ffc3d61bdd62ce1ae28f3fed1f91 Mon Sep 17 00:00:00 2001 From: 1000TurquoisePogs Date: Thu, 1 Sep 2022 15:19:05 -0400 Subject: [PATCH 28/28] Bugfix the printout message of configmgr, and version bump it Signed-off-by: 1000TurquoisePogs --- CHANGELOG.md | 1 + build/configmgr.proj.env | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e30bc943f..d57e3a675 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Bugfix for lht functions of collections.c to avoid memory issues on negative keys - Added a new build target, 'configmgr-rexx', which builds a version of configmgr that can be used within rexx scripts. +- Bugfix the help message on configmgr ## `2.2.0` diff --git a/build/configmgr.proj.env b/build/configmgr.proj.env index e14b41f06..b24079b03 100644 --- a/build/configmgr.proj.env +++ b/build/configmgr.proj.env @@ -1,5 +1,5 @@ PROJECT="configmgr" -VERSION=0.3.0 +VERSION=0.4.0 DEPS="QUICKJS LIBYAML" QUICKJS="quickjs"