diff options
Diffstat (limited to 'src/main/c/postshit')
-rw-r--r-- | src/main/c/postshit/launch/mvn/mvn-launch.c | 214 | ||||
-rw-r--r-- | src/main/c/postshit/launch/mvn/mvn-versions-set.c | 133 | ||||
-rw-r--r-- | src/main/c/postshit/launch/openshift/ocexec.c | 152 |
3 files changed, 499 insertions, 0 deletions
diff --git a/src/main/c/postshit/launch/mvn/mvn-launch.c b/src/main/c/postshit/launch/mvn/mvn-launch.c new file mode 100644 index 0000000..8886e9e --- /dev/null +++ b/src/main/c/postshit/launch/mvn/mvn-launch.c @@ -0,0 +1,214 @@ +/* + + Shitty policies require shitty workarounds. Standard maven ships with a 'cmd' + file for its execution. But as some shiny 'security' policies forbid + execution of 'cmd' files, we need to waste our time writing stuff like this + instead doing our work. Grrr... + + ${CC:?} -o build/bin/mvn-launch.exe \ + -Wall -Werror -fmax-errors=3 -Wno-error=unused-function -Wno-error=unused-variable \ + -DPROJECT_VERSION=0.0.0-$(date -u +%s) \ + src/main/c/postshit/launch/mvn/mvn-launch.c \ + +*/ + +#include <windows.h> +#include <assert.h> +#include <stdio.h> + +#define LOGERR(...) fprintf(stderr, __VA_ARGS__) +#define LOGDBG(...) fprintf(stderr, __VA_ARGS__) + +#define STR_QUOT_3q9o58uhzjad(s) #s +#define STR_QUOT(s) STR_QUOT_3q9o58uhzjad(s) + + +static int appendRaw( char*dst, int*dst_len, int dst_cap, const char*src, int src_len ){ + #define dst_len (*dst_len) + register int err; + if( dst_cap < dst_len + src_len ){ + LOGERR("ENOBUFS: %s Cannot add: %.*s\n", strrchr(__FILE__,'/')+1, src_len, src); + err = -ENOBUFS; goto endFn; + } + memcpy(dst + dst_len, src, src_len); + dst_len += src_len; + err = 0; +endFn: + return err; + #undef dst_len +} + + +static int appendQuotEscaped( char*dst, int*dst_len, int dst_cap, const char*src, int src_len ){ + #define dst_len (*dst_len) + register int err; + if( dst_cap < dst_len + src_len ){ + LOGDBG("ENOBUFS: %s: cannot append \"%.*s\"\n", strrchr(__FILE__,'/')+1, src_len, src); + err = -ENOBUFS; goto endFn; + } + for( err = 0 ; err < src_len ; ++err ){ + if( src[err] == '"' ){ + LOGERR("ENOTSUP: Quotes in args not impl. %s:%d\n", __FILE__, __LINE__); + err = -ENOTSUP; goto endFn; + } + dst[dst_len++] = src[err]; + } + err = 0; +endFn: + return err; + #undef dst_len +} + + +static int appendArg( char*cmdline, int*cmdline_len, int cmdline_cap, const char*newArg, int newArg_len ){ + #define cmdline_len (*cmdline_len) + register int err; + if( cmdline_cap < cmdline_len + newArg_len + sizeof" \"\"" ){ + LOGERR("ENOBUFS: Cmdline too long. %s:%d\n", strrchr(__FILE__,'/')+1, __LINE__); + err = -ENOBUFS; goto endFn; + } + cmdline[cmdline_len++] = ' '; + cmdline[cmdline_len++] = '"'; + for( err = 0 ; err < newArg_len ; ++err ){ + if( newArg[err] == '"' ){ + LOGERR("ENOTSUP: Quotes in args not impl. %s:%d\n", strrchr(__FILE__,'/')+1, __LINE__); + err = -ENOTSUP; goto endFn; + } + cmdline[cmdline_len++] = newArg[err]; + } + cmdline[cmdline_len++] = '"'; + err = 0; +endFn: + return err; + #undef cmdline_len +} + + +static int appendFromEnvironIfNotEmpty( char*cmdline, int*cmdline_len, int cmdline_cap, const char*envKey ){ + #define cmdline_len (*cmdline_len) + assert(envKey != NULL); + register int err; + char envval[0x7FFF]; + const int envval_cap = sizeof envval; + err = GetEnvironmentVariable(envKey, envval, envval_cap-1); + if( err >= envval_cap-1 ){ + LOGERR("ENOBUFS: environ.%s too long. %s:%d\n", envKey, strrchr(__FILE__,'/')+1, __LINE__); + err = -ENOBUFS; goto endFn; + } + if( err > 0 ){ + err = appendArg(cmdline, &cmdline_len, cmdline_cap, envval, err); + if( err < 0 ){ LOGDBG("[TRACE] at %s:%d\n", __FILE__, __LINE__); goto endFn; } + cmdline_len += err; + } + err = 0; +endFn: + return err; + #undef cmdline_len +} + + +int main( int argc, char**argv ){ + register int err; + + char tmp[2]; + err = GetEnvironmentVariable("LAUNCHR_HELP", tmp, 1); + if( err == 0 ){ + if( GetLastError() != ERROR_ENVVAR_NOT_FOUND ){ + LOGERR("ERROR: GetEnvironmentVariable(LAUNCHR_HELP): %lu. %s:%d\n", GetLastError(), __FILE__, __LINE__); + err = -1; goto endFn; } + /*no such variable. interpret as no-help-wanted*/; + }else{ + printf("\n %s " STR_QUOT(PROJECT_VERSION) "\n \n Delegates the call to maven without 'cmd' files.\n\n", strrchr(__FILE__,'/')+1); + err = -1; goto endFn; + } + + char username[16]; + const int username_cap = sizeof username; + err = GetEnvironmentVariable("USERNAME", username, username_cap); + if( err == 0 ){ LOGERR("ERROR: GetEnvironmentVariable(USERNAME) -> 0x%lX\n", GetLastError()); + err = -1; goto endFn; } + if( err > username_cap ){ + LOGERR("ENOBUFS: environ.USERNAME too long. %s:%d\n", strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + assert(err > 0); + const int username_len = err; + + char cmdline[32767]; /*[length](https://stackoverflow.com/questions/3205027/#comment17734587_3205048)*/ + cmdline[0] = '\0'; + const int cmdline_cap = sizeof cmdline; + int cmdline_len = 0; + + err = 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "C:/Users/", 9) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, username, username_len) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "/.opt/java/bin/java.exe", 23) < 0 + || appendFromEnvironIfNotEmpty(cmdline, &cmdline_len, cmdline_cap, "JVM_CONFIG_MAVEN_PROPS") < 0 + || appendFromEnvironIfNotEmpty(cmdline, &cmdline_len, cmdline_cap, "MAVEN_OPTS") < 0 + || appendFromEnvironIfNotEmpty(cmdline, &cmdline_len, cmdline_cap, "MAVEN_DEBUG_OPTS") < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " -classpath", 11) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " C:/Users/", 10) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, username, username_len) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "/.opt/maven/boot/plexus-classworlds-2.5.2.jar", 45) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " -Dclassworlds.conf=C:/Users/", 29) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, username, username_len) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "/.opt/maven/bin/m2.conf", 23) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " -Dmaven.home=C:/Users/", 23) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, username, username_len) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "/.opt/maven", 11) < 0 + ; + if( err ){ LOGDBG("[TRACE] at %s:%d\n", __FILE__, __LINE__); goto endFn; } + + char workDir[0x7FFF]; + const int workDir_cap = sizeof workDir; + err = GetCurrentDirectory(workDir_cap, workDir); + if( err == 0 ){ + LOGERR("ERROR: GetCurrentDirectory() -> 0x%lX. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + if( err >= workDir_cap ){ + LOGERR("ENOBUFS: Working dir too long. %s:%d\n", strrchr(__FILE__,'/')+1, __LINE__); + err = -ENOBUFS; goto endFn; } + assert(err > 0); + const int workDir_len = err; + for( err = 0 ; err < workDir_len ; ++err ){ if( workDir[err] == '\\' ) workDir[err] = '/'; } + + err = 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " \"-Dmaven.multiModuleProjectDirectory=", 38) < 0 + || appendQuotEscaped(cmdline, &cmdline_len, cmdline_cap, workDir, workDir_len) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "\"", 1) < 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, " org.codehaus.plexus.classworlds.launcher.Launcher", 50) < 0 + ; + if( err ){ LOGDBG("[TRACE] at %s:%d", __FILE__, __LINE__); err = -1; goto endFn; } + + /*append all other args*/ + for( int iA=1 ; iA < argc ; ++iA ){ + char *arg = argv[iA]; + err = appendArg(cmdline, &cmdline_len, cmdline_cap, arg, strlen(arg)); + if( err < 0 ){ LOGDBG("[TRACE] at %s:%d\n", __FILE__, __LINE__); goto endFn; } + } + + STARTUPINFOA startInfo = { .lpDesktop = NULL, .lpTitle = NULL, .dwFlags = 0, }; + startInfo.cb = sizeof(startInfo); + PROCESS_INFORMATION proc; + err = CreateProcessA(NULL, cmdline, NULL, NULL, !0, 0, NULL, NULL, &startInfo, &proc); + if( err == 0 ){ + LOGERR("ERROR: CreateProcess(): 0x%0lX. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; + } + err = WaitForSingleObject(proc.hProcess, INFINITE); + if( err != WAIT_OBJECT_0 ){ LOGERR("ERROR: WaitForSingleObject() -> %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + long unsigned exitCode; + err = GetExitCodeProcess(proc.hProcess, &exitCode); + if( err == 0 ){ LOGERR("ERROR: GetExitCodeProcess(): %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + if( (exitCode & 0x7FFFFFFF) != exitCode ){ + LOGERR("EDOM: Exit code %lu out of bounds. %s:%d\n", exitCode, strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; + } + err = exitCode; +endFn: + if( err != 0 && cmdline_len > 0 ){ LOGDBG("[DEBUG] %.*s\n", cmdline_len, cmdline); } + if( err < 0 ) err = -err; + return err; +} + diff --git a/src/main/c/postshit/launch/mvn/mvn-versions-set.c b/src/main/c/postshit/launch/mvn/mvn-versions-set.c new file mode 100644 index 0000000..888183d --- /dev/null +++ b/src/main/c/postshit/launch/mvn/mvn-versions-set.c @@ -0,0 +1,133 @@ +/* + + Shitty policies require shitty workarounds. Standard maven ships with a 'cmd' + file for its execution. But as some shiny 'security' policies forbid + execution of 'cmd' files, we need to waste our time writing stuff like this + instead doing our work. Grrr... + + ${CC:?} -o build/bin/mvn-versions-set.exe \ + -Wall -Werror -fmax-errors=3 -Wno-error=unused-function -Wno-error=unused-variable \ + -DPROJECT_VERSION=0.0.0-$(date -u +%s) \ + src/main/c/postshit/launch/mvn/mvn-versions-set.c \ + +*/ + +#include <windows.h> +#include <assert.h> +#include <stdio.h> + +#define LOGERR(...) fprintf(stderr, __VA_ARGS__) +#define LOGDBG(...) fprintf(stderr, __VA_ARGS__) + +#define STR_QUOT_3q9o58uhzjad(s) #s +#define STR_QUOT(s) STR_QUOT_3q9o58uhzjad(s) + + +static int appendRaw( char*dst, int*dst_len, int dst_cap, const char*src, int src_len ){ + #define dst_len (*dst_len) + register int err; + if( dst_cap < dst_len + src_len ){ + LOGERR("ENOBUFS: %s Cannot add: %.*s\n", strrchr(__FILE__,'/')+1, src_len, src); + err = -ENOBUFS; goto endFn; + } + memcpy(dst + dst_len, src, src_len); + dst_len += src_len; + err = 0; +endFn: + return err; + #undef dst_len +} + + +static int appendQuotEscaped( char*dst, int*dst_len, int dst_cap, const char*src, int src_len ){ + #define dst_len (*dst_len) + register int err; + if( dst_cap < dst_len + src_len ){ + LOGDBG("ENOBUFS: %s: cannot append \"%.*s\"\n", strrchr(__FILE__,'/')+1, src_len, src); + err = -ENOBUFS; goto endFn; + } + for( err = 0 ; err < src_len ; ++err ){ + if( src[err] == '"' ){ + LOGERR("ENOTSUP: Quotes in args not impl. %s:%d\n", __FILE__, __LINE__); + err = -ENOTSUP; goto endFn; + } + dst[dst_len++] = src[err]; + } + err = 0; +endFn: + return err; + #undef dst_len +} + + +int main( int argc, char**argv ){ + register int err; + int isHelp = 0; + const char *newVersion = NULL; + + /*parse args*/ + for( err = 1 ; err < argc ; ++err ){ + const char *arg = argv[err]; + if( !strcmp(arg, "--help") ){ + isHelp = !0; break; + }else if( newVersion == NULL ){ + newVersion = arg; + }else{ + LOGERR("EINVAL: Only ONE arg expected. But got: %s\n", arg); err = -1; goto endFn; + } + } + if( isHelp ){ + printf("\n" + " %s " STR_QUOT(PROJECT_VERSION) "\n" + " \n" + " Set a specific maven version. Usage:\n" + " \n" + " %s 0.0.0-SNAPSHOT\n" + "\n", strrchr(__FILE__,'/')+1, argv[0]); + err = -1; goto endFn; + } + if( newVersion == NULL ){ + LOGERR("EINVAL: new version to use missing. Try --help\n"); + err = -1; goto endFn; + } + const int newVersion_len = strlen(newVersion); + + char cmdline[32767]; /*[length](https://stackoverflow.com/questions/3205027/#comment17734587_3205048)*/ + cmdline[0] = '\0'; + const int cmdline_cap = sizeof cmdline; + int cmdline_len = 0; + + err = 0 + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "mvn versions:set -DgenerateBackupPoms=false \"-DnewVersion=", 58) < 0 + || appendQuotEscaped(cmdline, &cmdline_len, cmdline_cap, newVersion, newVersion_len) + || appendRaw(cmdline, &cmdline_len, cmdline_cap, "\"", 1) < 0 + ; + if( err ){ LOGDBG("[TRACE] at %s:%d", __FILE__, __LINE__); err = -1; goto endFn; } + + STARTUPINFOA startInfo = { .lpDesktop = NULL, .lpTitle = NULL, .dwFlags = 0, }; + startInfo.cb = sizeof(startInfo); + PROCESS_INFORMATION proc; + err = CreateProcessA(NULL, cmdline, NULL, NULL, !0, 0, NULL, NULL, &startInfo, &proc); + if( err == 0 ){ + LOGERR("ERROR: CreateProcess(): 0x%0lX. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; + } + err = WaitForSingleObject(proc.hProcess, INFINITE); + if( err != WAIT_OBJECT_0 ){ LOGERR("ERROR: WaitForSingleObject() -> %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + long unsigned exitCode; + err = GetExitCodeProcess(proc.hProcess, &exitCode); + if( err == 0 ){ LOGERR("ERROR: GetExitCodeProcess(): %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + if( (exitCode & 0x7FFFFFFF) != exitCode ){ + LOGERR("EDOM: Exit code %lu out of bounds. %s:%d\n", exitCode, strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; + } + err = exitCode; +endFn: + if( err != 0 && cmdline_len > 0 ){ LOGDBG("[DEBUG] %.*s\n", cmdline_len, cmdline); } + if( err < 0 ) err = -err; + return err; +} + + diff --git a/src/main/c/postshit/launch/openshift/ocexec.c b/src/main/c/postshit/launch/openshift/ocexec.c new file mode 100644 index 0000000..45c4af9 --- /dev/null +++ b/src/main/c/postshit/launch/openshift/ocexec.c @@ -0,0 +1,152 @@ +/* + +SH: true \ +SH: && `# Configure` \ +SH: && CC=x86_64-w64-mingw32-cc \ +SH: && MKDIR_P="mkdir -p" \ +SH: && CFLAGS="-Wall -Werror -pedantic -O0 -g -Isrc/main/c/common -DPROJECT_VERSION=0.0.0-$(date -u +%s) -fmax-errors=1 -Wno-error=unused-variable" \ +SH: && LDFLAGS="-Wl,--gc-sections,--as-needed" \ +SH: && `# Make` \ +SH: && ${MKDIR_P:?} build/bin \ +SH: && ${CC:?} -o build/bin/ocexec ${CFLAGS:?} src/main/c/postshit/launch/openshift/ocexec.c ${LDFLAGS:?} \ +SH: && true + +*/ + +#include <assert.h> +#include <stdio.h> +#include <string.h> +#if __WIN32 +# include <windoof.h> +#endif + +#define LOGERR(...) fprintf(stderr, __VA_ARGS__) +#if !NDEBUG +# define REGISTER +# define LOGDBG(...) fprintf(stderr, __VA_ARGS__) +#else +# define REGISTER register +# define LOGDBG(...) +#endif + +#define FLG_isHelp (1<<0) + + +typedef struct App App; + + +struct App { + int flg; + char const *ocNamespace; + char const *podName; +}; + + +static void printHelp( void ){ + printf(" \n" + " TODO write help page\n" + " \n"); +} + + +static int parseArgs( int argc, char**argv, App*app ){ + REGISTER int err; + int iArg = 1; + if( argc <= 1 ){ LOGERR("EINVAL: Luke.. use arguments!\n"); return-1; } +nextArg:; + char const *arg = argv[iArg++]; + if( arg == NULL ) goto verifyArgs; + if( !strcmp(arg,"--help") ){ + app->flg |= FLG_isHelp; + //LOGDBG("[DEBUG] help -> true\n", arg); + return 0; + }else if( !strcmp(arg,"-n") || !strcmp(arg,"--namespace") ){ + arg = argv[iArg++]; + if( arg == NULL ){ LOGERR("EINVAL: %s needs value\n", argv[iArg-2]); return-1; } + app->ocNamespace = arg; + //LOGDBG("[DEBUG] namespace -> \"%s\"\n", arg); + }else if( !strcmp(arg,"-p") || !strcmp(arg,"--pod") ){ + arg = argv[iArg++]; + if( arg == NULL ){ LOGERR("EINVAL: %s needs value\n", argv[iArg-2]); return-1; } + app->podName = arg; + //LOGDBG("[DEBUG] pod -> \"%s\"\n", arg); + }else{ + LOGERR("EINVAL: %s\n", arg); return -1; + } + goto nextArg; +verifyArgs: + return 0; +} + + +static int fetchPodnames( App*app ){ + assert(!"TODO_hCICALJrAgDwNgIAZ0ACAD9sAgB5UwIA"); + return -1; +} + + +static int resolvePodname( App*app ){ + REGISTER int err; + err = fetchPodnames(app); + if( err ) return err; + if( !strcmp(app->podName, "houston") ){ + } +} + + +static int resolveNamespace( App*app ){ + if(0){ + }else if( !strcmp(app->ocNamespace,"test") ){ + app->ocNamespace = "isa-houston-test"; + }else if( !strcmp(app->ocNamespace,"int") ){ + app->ocNamespace = "isa-houston-int"; + }else if( !strcmp(app->ocNamespace,"preprod") ){ + app->ocNamespace = "isa-houston-preprod"; + }else{ + LOGDBG("[DEBUG] Use oc namespace as provided: \"%s\"\n", app->ocNamespace); + } + return 0; +} + + +static int run( App*app ){ + REGISTER int err; + err = resolveNamespace(app); if( err ) return err; + err = resolvePodname(app); if( err ) return err; + + LOGDBG("ENOTSUP: TODO continue here %s:%d\n", __FILE__, __LINE__); + + PROCESS_INFORMATION proc; + err = CreateProcessA(NULL, cmdline, NULL, NULL, !0, 0, NULL, NULL, &startInfo, &proc); + if( err == 0 ){ + LOGERR("ERROR: CreateProcess(): 0x%0lX. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + err = WaitForSingleObject(proc.hProcess, INFINITE); + if( err != WAIT_OBJECT_0 ){ + LOGERR("ERROR: WaitForSingleObject() -> %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + long unsigned exitCode; + err = GetExitCodeProcess(proc.hProcess, &exitCode); + if( err == 0 ){ + LOGERR("ERROR: GetExitCodeProcess(): %lu. %s:%d\n", GetLastError(), strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; } + if( (exitCode & 0x7FFFFFFF) != exitCode ){ + LOGERR("EDOM: Exit code %lu out of bounds. %s:%d\n", exitCode, strrchr(__FILE__,'/')+1, __LINE__); + err = -1; goto endFn; + } +} + + +int main( int argc, char**argv ){ + REGISTER int err; + App app = {0}; assert((void*)0 == NULL); + #define app (&app) + if( parseArgs(argc, argv, app) ){ err = -1; goto endFn; } + LOGDBG("[DEBUG] flags are 0x%X\n", app->flg); + if( app->flg & FLG_isHelp ){ printHelp(); err = 0; goto endFn; } + err = run(app); +endFn: + return !!err; + #undef app +} + |