summaryrefslogtreecommitdiff
path: root/src/main/c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/c')
-rw-r--r--src/main/c/PcapOne/PcapOne.c311
-rw-r--r--src/main/c/common/assert_is.h39
-rw-r--r--src/main/c/common/commonbase.h (renamed from src/main/c/common/commonKludge.h)0
-rw-r--r--src/main/c/common/offset_of.h9
-rw-r--r--src/main/c/common/windoof.h59
-rw-r--r--src/main/c/paisa-fleet/FindFullDisks.c383
-rw-r--r--src/main/c/postshit/launch/mvn/mvn-launch.c214
-rw-r--r--src/main/c/postshit/launch/mvn/mvn-versions-set.c133
-rw-r--r--src/main/c/postshit/launch/openshift/ocexec.c152
9 files changed, 989 insertions, 311 deletions
diff --git a/src/main/c/PcapOne/PcapOne.c b/src/main/c/PcapOne/PcapOne.c
deleted file mode 100644
index 2eb9e25..0000000
--- a/src/main/c/PcapOne/PcapOne.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/* TODO fix this bullshit */
-typedef unsigned u_int;
-typedef unsigned short u_short;
-typedef unsigned char u_char;
-#include <pcap/pcap.h>
-/* endOf TODO */
-
-
-/* System */
-#include <assert.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-static char const*const DEV_STDIN = "/dev/stdin";
-
-#define FLG_isHelp (1<<0)
-#define FLG_isTcpPsh (1<<3)
-#define FLG_isTcpRst (1<<4)
-#define FLG_isTcpSyn (1<<5)
-#define FLG_isTcpFin (1<<6)
-#define FLG_isHttpReq (1<<7)
-#define FLG_isLlLinux (1<<12)
-#define FLG_isHdrPrinted (1<<13)
-#define FLG_INIT (0)
-
-typedef struct PcapOne PcapOne;
-
-
-struct PcapOne {
- uint_least16_t flg;
- const char *dumpFilePath;
- char *pcapErrbuf;
- pcap_t *pcap;
- unsigned long frameNr;
- struct/*most recent frame*/{
- int llProto;
- int llHdrEnd;
- };
- struct/*most recent packet*/{
- int netProto;
- int netBodyLen;
- int netHdrEnd;
- int_fast32_t netTotLen;
- uint_least32_t ipSrcAddr, ipDstAddr;
- };
- struct/*most recent segment*/{
- int trspBodyLen;
- int trspSrcPort, trspDstPort;
- int trspHdrEnd;
- };
- struct/*most recent http requst*/{
- const uint8_t *httpReqHeadline;
- int httpReqHeadline_len;
- int httpReq_off; /* pkg offset from begin of most recent request */
- };
-};
-
-
-/*BEG func fwd decl*/
-static void parse_ll_LINUX_SLL( PcapOne*, const struct pcap_pkthdr*, const u_char* );
-static void parse_net_IPv4( PcapOne*, const struct pcap_pkthdr*, const u_char* );
-static void parse_trsp_TCP( PcapOne*, const struct pcap_pkthdr*, const u_char* );
-static void parse_appl_HTTP_req( PcapOne*, const struct pcap_pkthdr*, const u_char* );
-static void printParsingResults( PcapOne*, const struct pcap_pkthdr* );
-/*END func fwd decl*/
-
-static void printHelp(){
- #define STRQUOT_21a9ffbe344c0792ed88688d6c676359(s) #s
- #define STRQUOT(s) STRQUOT_21a9ffbe344c0792ed88688d6c676359(s)
- const char *basename = "/"__FILE__ + sizeof("/"__FILE__);
- for(; basename[-1] != '/'; --basename );
- printf("%s%s%s", " \n"
- " ", basename, " " STRQUOT(PROJECT_VERSION) "\n"
- " \n"
- " Options:\n"
- " \n"
- " --pcap-stdin\n"
- " Like --pcap but reading from stdin.\n"
- " \n"
- " --pcap <path>\n"
- " Pcap file to operate on. Compressed files are NOT supported.\n"
- " \n");
- #undef STRQUOT_21a9ffbe344c0792ed88688d6c676359
- #undef STRQUOT
-}
-
-
-static int parseArgs( PcapOne*app, int argc, char**argv ){
- app->flg = FLG_INIT;
- app->dumpFilePath = NULL;
- for( int iA = 1 ; iA < argc ; ++iA ){
- const char *arg = argv[iA];
- if(0){
- }else if( !strcmp(arg,"--help") ){
- app->flg |= FLG_isHelp; return 0;
- }else if( !strcmp(arg,"--pcap") ){
- arg = argv[++iA];
- if( arg == NULL ){ fprintf(stderr, "EINVAL --pcap needs value\n"); return -1; }
- app->dumpFilePath = arg;
- }else if( !strcmp(arg,"--pcap-stdin") ){
- app->dumpFilePath = DEV_STDIN;
- }else{
- fprintf(stderr, "EINVAL: %s\n", arg); return -1;
- }
- }
- if( app->dumpFilePath == NULL ){
- fprintf(stderr, "EINVAL Arg missing: --pcap <path>\n"); return -1; }
- return 0;
-}
-
-
-static void onPcapPkg( u_char*user, const struct pcap_pkthdr*hdr, const u_char*buf ){
- PcapOne *const app = (void*)user;
-
- /* prepare for this new packet */
- app->frameNr += 1;
- app->flg &= ~(FLG_isTcpPsh | FLG_isTcpRst | FLG_isTcpSyn | FLG_isTcpFin | FLG_isHttpReq);
-
- /* data-link layer */
- switch( pcap_datalink(app->pcap) ){
- case 0x71: parse_ll_LINUX_SLL(app, hdr, buf); break;
- default: assert(!fprintf(stderr,"pcap_datalink() -> 0x%02X\n", pcap_datalink(app->pcap)));
- }
-
- /* network layer */
- switch( app->llProto ){
- case 0x0800: parse_net_IPv4(app, hdr, buf); break;
- default: printf("???, proto=0x%04X, network-layer\n", app->llProto); return;
- }
-
- /* transport layer */
- switch( app->netProto ){
- case 0x06: parse_trsp_TCP(app, hdr, buf); break;
- default: printf("???, proto=0x%02X, transport-layer\n", app->netProto); return;
- }
-
- assert(app->trspBodyLen >= 0);
-
- /* application layer, towards server */
- switch( app->trspDstPort ){
- case 80: parse_appl_HTTP_req(app, hdr, buf); break;
- case 7012: parse_appl_HTTP_req(app, hdr, buf); break;
- case 8080: parse_appl_HTTP_req(app, hdr, buf); break;
- }
-
- printParsingResults(app, hdr);
-}
-
-
-static void parse_ll_LINUX_SLL( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){
- assert(hdr->caplen >= 15);
- app->llProto = buf[14]<<8 | buf[15];
- app->llHdrEnd = 16;
-}
-
-
-static void parse_net_IPv4( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){
- assert(hdr->caplen >= app->llHdrEnd+19 && "TODO_775afde7f19010220e9df8d5e2924c3e");
- int_fast8_t netHdrLen = (buf[app->llHdrEnd+0] & 0x0F) * 4;
- app->netTotLen = buf[app->llHdrEnd+2] << 8 | buf[app->llHdrEnd+3];
- app->netProto = buf[app->llHdrEnd+9];
- app->ipSrcAddr = 0
- | ((uint_least32_t)buf[app->llHdrEnd+12]) << 24
- | ((uint_least32_t)buf[app->llHdrEnd+13]) << 16
- | buf[app->llHdrEnd+14] << 8
- | buf[app->llHdrEnd+15] ;
- app->ipDstAddr = 0
- | ((uint_least32_t)buf[app->llHdrEnd+16]) << 24
- | ((uint_least32_t)buf[app->llHdrEnd+17]) << 16
- | buf[app->llHdrEnd+18] << 8
- | buf[app->llHdrEnd+19] ;
- app->netHdrEnd = app->llHdrEnd + netHdrLen;
- app->netBodyLen = app->netTotLen - netHdrLen;
-}
-
-
-static void parse_trsp_TCP( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){
- assert(hdr->caplen >= app->netHdrEnd+12 && "TODO_058d5f41043d383e1ba2c492d0db4b6a");
- app->trspSrcPort = buf[app->netHdrEnd+0] << 8 | buf[app->netHdrEnd+1];
- app->trspDstPort = buf[app->netHdrEnd+2] << 8 | buf[app->netHdrEnd+3];
- int tcpHdrLen = (buf[app->netHdrEnd+12] >> 4) * 4;
- app->trspHdrEnd = app->netHdrEnd + tcpHdrLen;
- app->trspBodyLen = app->netBodyLen - tcpHdrLen;
-}
-
-
-static void parse_appl_HTTP_req( PcapOne*app, const struct pcap_pkthdr*hdr, const u_char*buf ){
- app->flg |= FLG_isHttpReq;
- app->httpReqHeadline = buf + app->trspHdrEnd;
- app->httpReqHeadline_len = 0;
- for(;; ++app->httpReqHeadline_len ){
- if( (app->trspHdrEnd + app->httpReqHeadline_len) > hdr->caplen ) break;
- if( app->httpReqHeadline[app->httpReqHeadline_len] == '\r' ) break;
- if( app->httpReqHeadline[app->httpReqHeadline_len] == '\n' ) break;
- }
- /* TODO improve, as now its like a guess only */
- int isNewRequest = 0
- | !memcmp(buf + app->trspHdrEnd, "GET ", 4)
- | !memcmp(buf + app->trspHdrEnd, "PUT ", 4)
- | !memcmp(buf + app->trspHdrEnd, "POST ", 5)
- | !memcmp(buf + app->trspHdrEnd, "DELETE ", 7)
- ;
- if( isNewRequest ){
- app->httpReq_off = 0;
- }else{
- app->httpReq_off = 42; /*TODO make more accurate*/
- }
-}
-
-
-static void printParsingResults( PcapOne*app, const struct pcap_pkthdr*hdr ){
-
- int isHttpRequest = (app->flg & FLG_isHttpReq);
- int isHttpReqBegin = isHttpRequest && app->httpReq_off == 0;
-
- if( isHttpRequest && isHttpReqBegin ){
- /* find http method */
- const uint8_t *method = app->httpReqHeadline;
- int method_len = 0;
- for(;; ++method_len ){
- if( method_len > app->httpReqHeadline_len ) break;
- if( method[method_len] == ' ' ) break;
- }
- /* find http uri */
- const uint8_t *uri = method + method_len + 1;
- int uri_len = 0;
- for(;; ++uri_len ){
- if( method_len + uri_len > app->httpReqHeadline_len ) break;
- if( uri[uri_len] == ' ' ) break;
- }
- if( !(app->flg & FLG_isHdrPrinted) ){
- app->flg |= FLG_isHdrPrinted;
- printf("h;Title;HTTP requests\n");
- printf("c;epochSec;srcIp;dstIp;srcPort;dstPort;http_method;http_uri\n");
- }
- /* print it as a quick-n-dirty CSV record */
- printf("r;%ld.%06ld;%d.%d.%d.%d;%d.%d.%d.%d;%d;%d;%.*s;%.*s\n",
- hdr->ts.tv_sec, hdr->ts.tv_usec,
- app->ipSrcAddr >> 24, app->ipSrcAddr >> 16 & 0xFF, app->ipSrcAddr >> 8 & 0xFF, app->ipSrcAddr & 0xFF,
- app->ipDstAddr >> 24, app->ipDstAddr >> 16 & 0xFF, app->ipDstAddr >> 8 & 0xFF, app->ipDstAddr & 0xFF,
- app->trspSrcPort, app->trspDstPort,
- method_len, method, uri_len, uri);
- }
-}
-
-
-static int run( PcapOne*app ){
- int err;
- err = pcap_init(PCAP_CHAR_ENC_UTF_8, app->pcapErrbuf);
- if( err == PCAP_ERROR ){
- fprintf(stderr, "libpcap: %s\n", app->pcapErrbuf); err = -1; goto endFn; }
- app->pcap = pcap_open_offline(
- (app->dumpFilePath == DEV_STDIN) ? "-" : app->dumpFilePath,
- app->pcapErrbuf);
- if( app->pcap == NULL ){
- fprintf(stderr, "libpcap: %s\n", app->pcapErrbuf); err = -1; goto endFn; }
- for(;;){
- err = pcap_dispatch(app->pcap, -1, onPcapPkg, (void*)app);
- switch( err ){
- case PCAP_ERROR:
- fprintf(stderr, "pcap_dispatch(): %s\n", pcap_geterr(app->pcap));
- err = -1; goto endFn;
- case PCAP_ERROR_BREAK:
- case PCAP_ERROR_NOT_ACTIVATED:
- fprintf(stderr, "pcap_dispatch() -> %d\n", err);
- err = -1; goto endFn;
- }
- if( err > 0 ){
- fprintf(stderr, "Processed %d packages in this turn.\n", err);
- continue;
- }
- break;
- }
- err = 0;
-endFn:
- if( app->pcap != NULL ){ pcap_close(app->pcap); app->pcap = NULL; }
- return err;
-}
-
-
-int main( int argc, char**argv ){
- int err;
- static char errbuf[PCAP_ERRBUF_SIZE];
- errbuf[0] = '\0';
- PcapOne app = {
- .flg = FLG_INIT,
- .pcapErrbuf = errbuf,
- .pcap = NULL,
- .frameNr = 0,
- .trspBodyLen = 0,
- };
- #define app (&app)
-
- err = parseArgs(app, argc, argv);
- if( err ){ goto endFn; }
-
- if( app->flg & FLG_isHelp ){
- printHelp(); goto endFn; }
-
- err = run(app);
-
-endFn:
- if( err < 0 ) err = -err;
- if( err > 0x7F ) err = 1;
- return err;
- #undef app
-}
-
-
diff --git a/src/main/c/common/assert_is.h b/src/main/c/common/assert_is.h
new file mode 100644
index 0000000..316bf02
--- /dev/null
+++ b/src/main/c/common/assert_is.h
@@ -0,0 +1,39 @@
+
+#if !NDEBUG
+#define TPL_assert_is(T, PRED) static inline T*assert_is_##T(void*p,\
+const char*f,int l){if(p==NULL){fprintf(stderr,"assert(" STR_QUOT(T)\
+" != NULL) %s:%d\n",f,l);abort();}T*obj=p;if(!(PRED)){fprintf(stderr,\
+"ssert(type is \""STR_QUOT(T)"\") %s:%d\n",f,l);abort();}return p; }
+#else
+#define TPL_assert_is(T, PRED) static inline T*assert_is_##T(void*p,\
+const char*f,int l){return p;}
+#endif
+
+
+
+/* Example usage: */
+
+/* add some magic to your struct under check */
+typedef struct Person Person;
+struct Person {
+ char tYPE[sizeof"Hi, I'm a Person"];
+};
+
+/* instantiate a checker */
+TPL_assert_is(Person, !strcmp(obj->tYPE, "Hi, I'm a Person"))
+#define assert_is_Person(p) assert_is_Person(p, __FILE__, __LINE__)
+
+/* make sure magic is initialized (ALSO MAKE SURE TO PROPERLY INVALIDATE
+ * IT IN DTOR!)*/
+static void someCaller( void ){
+ Person p = {0};
+ strcpy(p.tYPE, "Hi, I'm a Person");
+ void *ptr = p; /*whops compiler cannot help us any longer*/
+ someCallee(ptr);
+}
+
+/* verify you reall got a Person*/
+static void someCallee( void*shouldBeAPerson ){
+ Person *p = assert_is_Person(shouldBeAPerson);
+}
+
diff --git a/src/main/c/common/commonKludge.h b/src/main/c/common/commonbase.h
index e0f0cba..e0f0cba 100644
--- a/src/main/c/common/commonKludge.h
+++ b/src/main/c/common/commonbase.h
diff --git a/src/main/c/common/offset_of.h b/src/main/c/common/offset_of.h
new file mode 100644
index 0000000..7d9179d
--- /dev/null
+++ b/src/main/c/common/offset_of.h
@@ -0,0 +1,9 @@
+#ifndef INCGUARD_yisgKqALPG4lfEqb
+#define INCGUARD_yisgKqALPG4lfEqb
+
+
+#define container_of(P, T, M) \
+ ((T*)( ((size_t)P) - ((size_t)((char*)&((T*)0)->M - (char*)0) )))
+
+
+#endif /* INCGUARD_yisgKqALPG4lfEqb */
diff --git a/src/main/c/common/windoof.h b/src/main/c/common/windoof.h
new file mode 100644
index 0000000..6ed9b41
--- /dev/null
+++ b/src/main/c/common/windoof.h
@@ -0,0 +1,59 @@
+
+#if 0
+# include <windows.h>
+#else
+
+#include <stdint.h>
+
+//#define HANDLE void*
+//typedef int BOOL;
+//typedef unsigned long LPDWORD;
+
+
+typedef struct _PROCESS_INFORMATION {
+ void* hProcess;
+ void* hThread;
+ uint32_t dwProcessId;
+ uint32_t dwThreadId;
+} PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
+
+
+typedef struct _SECURITY_ATTRIBUTES {
+ uint32_t nLength;
+ void* lpSecurityDescriptor;
+ int bInheritHandle;
+} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
+
+
+typedef struct _STARTUPINFOA {
+ uint32_t cb;
+ char *lpReserved;
+ char *lpDesktop;
+ char *lpTitle;
+ uint32_t dwX;
+ uint32_t dwY;
+ uint32_t dwXSize;
+ uint32_t dwYSize;
+ uint32_t dwXCountChars;
+ uint32_t dwYCountChars;
+ uint32_t dwFillAttribute;
+ uint32_t dwFlags;
+ short wShowWindow;
+ short cbReserved2;
+ uint8_t lpReserved2;
+ void *hStdInput, *hStdOutput, *hStdError;
+} STARTUPINFOA, *LPSTARTUPINFOA;
+
+
+
+int CreateProcessA( char const*, char*, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, int, uint32_t,
+ void*, char const*, LPSTARTUPINFOA, LPPROCESS_INFORMATION );
+
+
+int GetExitCodeProcess(void*, unsigned long*);
+
+
+
+
+
+#endif /*manual windoof on/off switch*/
diff --git a/src/main/c/paisa-fleet/FindFullDisks.c b/src/main/c/paisa-fleet/FindFullDisks.c
new file mode 100644
index 0000000..429b71c
--- /dev/null
+++ b/src/main/c/paisa-fleet/FindFullDisks.c
@@ -0,0 +1,383 @@
+#if 0
+
+true `# configure FindFullDisks for NORMAL systems` \
+ && CC=gcc \
+ && MKDIR_P="mkdir -p" \
+ && CFLAGS="-Wall -Werror -pedantic -Os -fmax-errors=1 -Wno-error=unused-variable -Wno-error=unused-function -Isrc/main/c -Iimport/include" \
+ && LDFLAGS="-Wl,-dn,-lgarbage,-lcJSON,-lexpat,-lmbedtls,-lmbedx509,-lmbedcrypto,-dy,-lpthread,-lws2_w32,-Limport/lib" \
+ && true
+
+true `# configure FindFullDisks for BROKEN systems` \
+ && CC=x86_64-w64-mingw32-gcc \
+ && MKDIR_P="mkdir -p" \
+ && CFLAGS="-Wall -Werror -pedantic -Os -fmax-errors=1 -Wno-error=unused-variable -Wno-error=unused-function -Isrc/main/c -Iimport/include" \
+ && LDFLAGS="-Wl,-dn,-lgarbage,-lcJSON,-lexpat,-lmbedtls,-lmbedx509,-lmbedcrypto,-dy,-lws2_32,-Limport/lib" \
+ && true
+
+true `# make FindFullDisks` \
+ && ${MKDIR_P:?} build/bin \
+ && ${CC:?} -o build/bin/findfulldisks $CFLAGS src/main/c/paisa-fleet/FindFullDisks.c $LDFLAGS \
+ && true
+
+#endif
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "Garbage.h"
+
+#define FLG_isHelp (1<<0)
+
+#if !NDEBUG
+# define REGISTER register
+# define LOGDBG(...) fprintf(stderr, __VA_ARGS__)
+# define IF_DBG(expr) expr
+#else
+# define REGISTER
+# define LOGDBG(...)
+# define IF_DBG(expr)
+#endif
+#define LOGERR(...) fprintf(stderr, __VA_ARGS__)
+
+
+
+typedef struct FindFullDisks FindFullDisks;
+typedef struct Device Device;
+
+
+#define MAGIC_FindFullDisks 0xB5410200
+struct FindFullDisks {
+ IF_DBG(int mAGIC);
+ int flg;
+ const char *sshUser;
+ int sshPort;
+ int maxParallel, numInProgress;
+ struct GarbageEnv **env;
+ struct Garbage_CsvIStream **csvSrc;
+ struct Garbage_Process **child;
+ char *inBuf;
+ int inBuf_cap, inBuf_len;
+ Device *devices;
+ int devices_cap, devices_cnt;
+ int iDevice; /* Next device to be triggered. */
+ int exitCode;
+};
+
+
+#define MAGIC_Device 0xAB420200
+struct Device {
+ IF_DBG(int mAGIC);
+ struct FindFullDisks *app;
+ char hostname[sizeof"lunkwill-0123456789AB_____"];
+ char eddieName[sizeof"eddie12345_____"];
+ char stdoutBuf[8192];
+ int stdoutBuf_cap, stdoutBuf_len;
+};
+
+
+/*BEG fwd decls*/
+static void beginNextDevice( void* );
+static void feedNextChunkFromStdinToCsvParser( void* );
+/*END fwd decls*/
+
+
+static void printHelp( void ){
+ printf("%s%s%s", " \n"
+ " ", strrchr(__FILE__,'/')+1, "\n"
+ " \n"
+ " Expected format on stdin is a CSV like:\n"
+ " \n"
+ " eddie00042 <SEMICOLON> lunkwill-ABBABEAFABBA <LF>\n"
+ " ...\n"
+ " \n"
+ " Options:\n"
+ " \n"
+ " --sshUser <str>\n"
+ " \n"
+ " --sshPort <int>\n"
+ " Default: 22\n"
+ " \n"
+ " --maxParallel <int>\n"
+ " Default 1.\n"
+ " \n");
+}
+
+
+static int parseArgs( int argc, char**argv, FindFullDisks*app ){
+ int iA = 1;
+ app->sshUser = NULL;
+ app->sshPort = 22;
+ app->maxParallel = 1;
+nextArg:;
+ const char *arg = argv[iA++];
+ if( arg == NULL ) goto validateArgs;
+ if( !strcmp(arg, "--help")){
+ app->flg |= FLG_isHelp; return 0;
+ }else if( !strcmp(arg, "--sshUser")){
+ arg = argv[iA++];
+ if( arg == NULL ){ LOGERR("EINVAL: Arg --sshUser needs value\n"); return -1; }
+ app->sshUser = arg;
+ }else if( !strcmp(arg, "--sshPort")){
+ arg = argv[iA++];
+ if( arg == NULL ){ LOGERR("EINVAL: Arg --sshPort needs value\n"); return -1; }
+ errno = 0;
+ app->sshPort = strtol(arg, NULL, 0);
+ if( errno ){ LOGERR("EINVAL: --sshPort %s\n", arg); return -1; }
+ }else if( !strcmp(arg, "--maxParallel")){
+ arg = argv[iA++];
+ if( arg == NULL ){ LOGERR("EINVAL: Arg --maxParallel needs value\n"); return -1; }
+ errno = 0;
+ app->maxParallel = strtol(arg, NULL, 0);
+ if( errno ){ LOGERR("EINVAL: --maxParallel %s\n", arg); return -1; }
+ }else{
+ LOGERR("EINVAL: %s\n", arg);
+ }
+ goto nextArg;
+validateArgs:;
+ if( app->sshUser == NULL ){ LOGERR("EINVAL: Arg --sshUser missing\n"); return -1; }
+ return 0;
+}
+
+
+static void no_op( void*_ ){}
+
+
+static void examineDeviceResult( void*device_ ){
+ REGISTER int err;
+ Device*const device = device_; assert(device->mAGIC = MAGIC_Device);
+ //FindFullDisks*const app = device->app; assert(app->mAGIC == MAGIC_FindFullDisks);
+ FILE *outFd = NULL;
+ if( device->stdoutBuf_len <= 0 ){ /*nothing to do*/ goto endFn; }
+ char outName[sizeof"result/eddie12345-lunkwill-1234567890123456.log"];
+ err = snprintf(outName, sizeof outName, "result/%s-%s.log", device->eddieName, device->hostname);
+ assert(err < sizeof outName);
+ outFd = fopen(outName, "wb");
+ if( outFd == NULL ){ LOGDBG("assert(fopen(%s) != %d) %s:%d\n", outName, errno, __FILE__, __LINE__); abort(); }
+ err = fwrite(device->stdoutBuf, 1, device->stdoutBuf_len, outFd);
+ assert(err == device->stdoutBuf_len);
+endFn:
+ if( outFd != NULL ) fclose(outFd);
+}
+
+
+static void Child_onStdout( const char*buf, int buf_len, void*cls ){
+ Device*const device = cls; assert(device->mAGIC = MAGIC_Device);
+ FindFullDisks*const app = device->app; assert(app->mAGIC == MAGIC_FindFullDisks);
+ if( buf_len > 0 ){ /*another chunk*/
+ if( device->stdoutBuf_len + buf_len >= device->stdoutBuf_cap ) assert(!"TODO_VD8CAIVAgBDwIA4mECAKVjAgB1XwIAfk");
+ memcpy(device->stdoutBuf + device->stdoutBuf_len, buf, buf_len);
+ device->stdoutBuf_len += buf_len;
+ //printf("%.*s", buf_len, buf);
+ }else{ /*EOF*/
+ assert(buf_len == 0);
+ }
+}
+
+
+static void Child_onJoined( int retval, int exitCode, int sigNum, void*cls ){
+ Device*const device = cls; assert(device->mAGIC == MAGIC_Device);
+ FindFullDisks*const app = device->app; assert(app->mAGIC == MAGIC_FindFullDisks);
+ if( retval != 0 || exitCode != 0 || sigNum != 0 ){
+ LOGDBG("[DEBUG] %s(%d, %d, %d)\n", __func__, retval, exitCode, sigNum);
+ }
+ assert(app->numInProgress > 0);
+ app->numInProgress -= 1;
+ (*app->env)->enqueBlocking(app->env, examineDeviceResult, device);
+ (*app->env)->enqueBlocking(app->env, beginNextDevice, app);
+}
+
+
+static void visitDevice( FindFullDisks*app, Device*device ){
+ assert(device != NULL && device->mAGIC == MAGIC_Device);
+ assert(device < app->devices + app->devices_cnt);
+ LOGERR("\n[INFO ] %s \"%s\" (behind \"%s\")\n", __func__, device->hostname, device->eddieName);
+ int err;
+ char eddieCmd[2048];
+ //err = snprintf(eddieCmd, sizeof eddieCmd, "true"
+ // " && HOSTNAME=$(hostname|sed 's_.pnet.ch__')"
+ // " && STAGE=$PAISA_ENV"
+ // " && printf \"remoteEddieName=$HOSTNAME, remoteStage=$STAGE\\n\""
+ // " && if test \"$(echo ${HOSTNAME}|sed -E 's_^vted_teddie_g')\" != \"%s\"; then true"
+ // " && echo wrong host. Want %s found $HOSTNAME && false"
+ // " ;fi"
+ // " && df",
+ // device->eddieName, device->eddieName
+ //);
+ err = snprintf(eddieCmd, sizeof eddieCmd, "true"
+ " && HOSTNAME=$(hostname|sed 's_.pnet.ch__')"
+ " && STAGE=$PAISA_ENV"
+ " && printf \"remoteEddieName=$HOSTNAME, remoteStage=$STAGE\\n\""
+ " && if test \"$(echo ${HOSTNAME}|sed -E 's_^vted_teddie_g')\" != \"%s\"; then true"
+ " && echo wrong host. Want %s found $HOSTNAME && false"
+ " ;fi"
+ " && ssh -oStrictHostKeyChecking=no -oUserKnownHostsFile=/dev/null"
+ " -p%d %s@%s"
+ " -- sh -c 'true"
+ " && HOSTNAME=$(hostname|sed '\"'\"'s_.isa.localdomain__'\"'\"')"
+ " && STAGE=$PAISA_ENV"
+ " && printf \"remoteHostname=$HOSTNAME, remoteStage=$STAGE\\n\""
+ // on some machine, df failed with "Stale file handle" But I want to
+ // continue with next device regardless of such errors.
+ " && df || true"
+ "'",
+ device->eddieName, device->eddieName, app->sshPort, app->sshUser,
+ strncmp("fook-",device->hostname,5) ? device->hostname : "fook"
+ );
+ assert(err < sizeof eddieCmd);
+ assert(app->sshPort > 0 && app->sshPort <= 0xFFFF);
+ char sshPortStr[sizeof"65535"];
+ err = snprintf(sshPortStr, sizeof sshPortStr, "%d", app->sshPort);
+ assert(err < (int)sizeof sshPortStr);
+ char userAtEddie[64];
+ err = snprintf(userAtEddie, sizeof userAtEddie, "%s@%s", app->sshUser, device->eddieName);
+ assert(err < sizeof userAtEddie);
+ char *childArgv[] = { "ssh",
+ "-oRemoteCommand=none",
+ "-oStrictHostKeyChecking=no",
+ "-oUserKnownHostsFile=/dev/null",
+ "-oConnectTimeout=4",
+ "-p", sshPortStr,
+ userAtEddie,
+ "--", "sh", "-c", eddieCmd,
+ NULL
+ };
+ //LOGDBG("CMDLINE:");
+ //for( int i = 0 ; childArgv[i] != NULL ; ++i ) LOGDBG(" \"%s\"", childArgv[i]);
+ //LOGDBG("\n\n");
+ app->child = (*app->env)->newProcess(app->env, &(struct Garbage_Process_Mentor){
+ .cls = device,
+ .usePathSearch = !0,
+ .argv = childArgv,
+ .onStdout = Child_onStdout,
+ //.onStderr = ,
+ .onJoined = Child_onJoined,
+ });
+ assert(app->child != NULL);
+ (*app->child)->join(app->child, 42000);
+}
+
+
+static void beginNextDevice( void*cls ){
+ FindFullDisks*const app = cls; assert(app->mAGIC == MAGIC_FindFullDisks);
+maybeBeginAnotherOne:
+ if( app->numInProgress >= app->maxParallel ){
+ //LOGDBG("[DEBUG] Already %d/%d in progress. Do NOT trigger more for now.\n",
+ // app->numInProgress, app->maxParallel);
+ goto endFn;
+ }
+ if( app->iDevice >= app->devices_cnt ){
+ //LOGDBG("[INFO ] Work on %d devices triggered. No more devices to trigger.\n", app->iDevice);
+ goto endFn;
+ }
+ assert(app->iDevice >= 0 && app->iDevice < INT_MAX);
+ app->iDevice += 1;
+ assert(app->numInProgress >= 0 && app->numInProgress < INT_MAX);
+ app->numInProgress += 1;
+ visitDevice(app, app->devices + app->iDevice - 1);
+ goto maybeBeginAnotherOne;
+endFn:;
+}
+
+
+static void onCsvRow( struct Garbage_CsvIStream_BufWithLength*row, int numCols, void*cls ){
+ REGISTER int err;
+ FindFullDisks*const app = cls; assert(app->mAGIC == MAGIC_FindFullDisks);
+ if( app->exitCode ) return;
+ if( numCols != 2 ){
+ LOGERR("[ERROR] Expected 2 column in input CSV but found %d\n", numCols);
+ app->exitCode = -1; return;
+ }
+ if( app->devices_cap <= app->devices_cnt ){
+ app->devices_cap += 4096;
+ void *tmp = realloc(app->devices, app->devices_cap*sizeof*app->devices);
+ if( tmp == NULL ) assert(!"TODO_c04CAJtRAgDYWQIAm10CAOAeAgA0KgIA");
+ app->devices = tmp;
+ }
+ #define DEVICE (app->devices + app->devices_cnt)
+ IF_DBG(DEVICE->mAGIC = MAGIC_Device);
+ DEVICE->app = app;
+ DEVICE->stdoutBuf_cap = sizeof DEVICE->stdoutBuf / sizeof*DEVICE->stdoutBuf;
+ if( row[0].len >= sizeof DEVICE->eddieName ){
+ LOGERR("[ERROR] eddieName too long: len=%d\n", row[0].len);
+ app->exitCode = -1; return;
+ }
+ if( row[1].len >= sizeof DEVICE->hostname ){
+ LOGERR("[ERROR] hostname too long: len=%d\n", row[1].len);
+ app->exitCode = -1; return;
+ }
+ memcpy(DEVICE->eddieName, row[0].buf, row[0].len);
+ DEVICE->eddieName[row[0].len] = '\0';
+ memcpy(DEVICE->hostname, row[1].buf, row[1].len);
+ DEVICE->hostname[row[1].len] = '\0';
+ #undef DEVICE
+ app->devices_cnt += 1;
+}
+
+
+static void onCsvParserCloseSnkDone( int retval, void*app_ ){
+ FindFullDisks*const app = app_; assert(app->mAGIC == MAGIC_FindFullDisks);
+ LOGDBG("[DEBUG] Found %d devices in input.\n", app->devices_cnt);
+ (*app->env)->enqueBlocking(app->env, beginNextDevice, app);
+}
+
+
+static void onCsvParserWriteDone( int retval, void*cls ){
+ FindFullDisks*const app = cls; assert(app->mAGIC == MAGIC_FindFullDisks);
+ if( retval <= 0 ){ LOGDBG("assert(retval != %d) %s:%d\n", retval, __FILE__, __LINE__); abort(); }
+ (*app->env)->enqueBlocking(app->env, feedNextChunkFromStdinToCsvParser, app);
+}
+
+
+static void feedNextChunkFromStdinToCsvParser( void*cls ){
+ REGISTER int err;
+ FindFullDisks*const app = cls; assert(app->mAGIC == MAGIC_FindFullDisks);
+ if( app->exitCode ) return;
+ #define SRC (stdin)
+ if( app->inBuf == NULL || app->inBuf_cap < 1<<15 ){
+ app->inBuf_cap = 1<<15;
+ if( app->inBuf ) free(app->inBuf);
+ app->inBuf = malloc(app->inBuf_cap*sizeof*app->inBuf);;
+ if( app->inBuf == NULL ){ assert(!"TODO_TT8CAGQLAgCoawIA9jgCANA6AgBTaAIA"); }
+ }
+ err = fread(app->inBuf, 1, app->inBuf_cap, SRC);
+ if( err <= 0 ){
+ (*app->csvSrc)->closeSnk(app->csvSrc, onCsvParserCloseSnkDone, app);
+ return;
+ }
+ app->inBuf_len = err;
+ (*app->csvSrc)->write(app->inBuf, app->inBuf_len, app->csvSrc, onCsvParserWriteDone, app);
+ #undef SRC
+}
+
+
+static void initCsvParserForDeviceListOnStdin( void*cls ){
+ FindFullDisks*const app = cls; assert(app->mAGIC == MAGIC_FindFullDisks);
+ static struct Garbage_CsvIStream_Mentor csvMentor = {
+ .onCsvRow = onCsvRow,
+ .onCsvDocEnd = no_op,
+ };
+ struct Garbage_CsvIStream_Opts csvOpts = { .delimCol = ';' };
+ app->csvSrc = (*app->env)->newCsvIStream(app->env, &csvOpts, &csvMentor, app);
+ feedNextChunkFromStdinToCsvParser(app);
+}
+
+
+int main( int argc, char**argv ){
+ void *envMemory[SIZEOF_struct_GarbageEnv/sizeof(void*)];
+ FindFullDisks app = {0}; assert((void*)0 == NULL);
+ #define app (&app)
+ IF_DBG(app->mAGIC = MAGIC_FindFullDisks);
+ if( parseArgs(argc, argv, app) ){ app->exitCode = -1; goto endFn; }
+ if( app->flg & FLG_isHelp ){ printHelp(); goto endFn; }
+ app->env = GarbageEnv_ctor(envMemory, sizeof envMemory);
+ assert(app->env != NULL);
+ (*app->env)->enqueBlocking(app->env, initCsvParserForDeviceListOnStdin, app);
+ (*app->env)->runUntilDone(app->env);
+endFn:
+ return !!app->exitCode;
+ #undef app
+}
+
+
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
+}
+