From 55553c2fdb4c1c64dab98f8f778d6137ce95b484 Mon Sep 17 00:00:00 2001 From: Erik Beeson Date: Fri, 26 Apr 2019 00:09:05 -0700 Subject: [PATCH 1/6] Switch to using libcurl instead of system call to curl CLI (cherry picked from commit 5a68917469e6a4a29e932d2d6dab56e5b6ab312b) # Conflicts: # DistributedChaffinMethod/DistributedChaffinMethod.c # DistributedChaffinMethod/Readme.txt --- .../DistributedChaffinMethod.c | 74 ++++++++++++++----- 1 file changed, 57 insertions(+), 17 deletions(-) diff --git a/DistributedChaffinMethod/DistributedChaffinMethod.c b/DistributedChaffinMethod/DistributedChaffinMethod.c index 881bc53..fa5578b 100644 --- a/DistributedChaffinMethod/DistributedChaffinMethod.c +++ b/DistributedChaffinMethod/DistributedChaffinMethod.c @@ -43,6 +43,7 @@ another instance of the program. #include #include #include +#include #include #include #include @@ -126,11 +127,6 @@ another instance of the program. #define DBITS 3 -// Command-line utility that gets response from a supplied URL -// Current choice is curl (with options to suppress progress meter but display any errors) - -#define URL_UTILITY "curl --silent --show-error " - // Name of temporary file in which response from server is placed #define SERVER_RESPONSE_FILE_NAME_TEMPLATE "DCMServerResponse_%u.txt" @@ -1660,7 +1656,15 @@ return res; #endif -// Send a command string via URL_UTILITY to the server at SERVER_URL, putting the response in the file SERVER_RESPONSE_FILE_NAME +// Process response from server + +static size_t write_curl_data(void *ptr, size_t size, size_t nmemb, void *stream) +{ +size_t written = fwrite(ptr, size, nmemb, (FILE *)stream); +return written; +} + +// Send a command string via libcurl to the server at SERVER_URL, putting the response in the file SERVER_RESPONSE_FILE_NAME // // Returns non-zero if an error was encountered @@ -1700,22 +1704,58 @@ if (fp==NULL) }; fclose(fp); -size_t ulen = strlen(URL_UTILITY); size_t slen = strlen(SERVER_URL); size_t clen = strlen(command); -size_t flen = strlen(SERVER_RESPONSE_FILE_NAME); -size_t len = ulen+slen+clen+flen+10; -char *cmd; -CHECK_MEM( cmd = malloc(len*sizeof(char)) ) -sprintf(cmd,"%s \"%s%s\" > %s",URL_UTILITY,SERVER_URL,command,SERVER_RESPONSE_FILE_NAME); -int res = system(cmd); -free(cmd); +size_t len = slen+clen; +char *url; +CHECK_MEM( url = malloc(len*sizeof(char)) ) +sprintf(url, "%s%s", SERVER_URL, command); -// Release local lock on server access +CURL *curl; +CURLcode res; -releaseServerLock(); +curl_global_init(CURL_GLOBAL_ALL); -return res; +/* init the curl session */ +curl = curl_easy_init(); + +curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.60.0"); + +/* set URL to get here */ +curl_easy_setopt(curl, CURLOPT_URL, url); + +/* disable progress meter, set to 0L to enable and disable debug output */ +curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + +/* send all data to this function */ +curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_curl_data); + +/* open the file */ +fp = fopen(SERVER_RESPONSE_FILE_NAME, "wt"); +if (fp) + { + /* write the page body to this file handle */ + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); + + /* get it! */ + res = curl_easy_perform(curl); + + /* close the header file */ + fclose(fp); + } +else + { + printf("Error: Unable to write to server response file %s\n",SERVER_RESPONSE_FILE_NAME); + exit(EXIT_FAILURE); + } +/* cleanup curl stuff */ +curl_easy_cleanup(curl); + +curl_global_cleanup(); + +free(url); + +return (res != CURLE_OK) ? 1 : 0; } #endif From 01583172b0ea2e2fb23baed9367158f58b4c4ee5 Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Fri, 10 May 2019 18:28:17 +0100 Subject: [PATCH 2/6] Remove getServerInstanceCount related code as that was calling curl directly --- .../DistributedChaffinMethod.c | 70 ------------------- 1 file changed, 70 deletions(-) diff --git a/DistributedChaffinMethod/DistributedChaffinMethod.c b/DistributedChaffinMethod/DistributedChaffinMethod.c index fa5578b..d7204c6 100644 --- a/DistributedChaffinMethod/DistributedChaffinMethod.c +++ b/DistributedChaffinMethod/DistributedChaffinMethod.c @@ -76,10 +76,6 @@ another instance of the program. // Constants // --------- -// Choose whether to use an "InstanceCount" file on the server to avoid running more than one PHP process at once - -#define USE_SERVER_INSTANCE_COUNTS FALSE - // Choose whether to use a "server lock" file on the client computer to coordinate server access between multiple client instances #define USE_SERVER_LOCK_FILE FALSE @@ -93,14 +89,6 @@ another instance of the program. #define SERVER_URL "http://ada.mscsnet.mu.edu/ChaffinMethod.php?version=9&" -#if USE_SERVER_INSTANCE_COUNTS - -// URL for InstanceCount file - - #define IC_URL "http://ada.mscsnet.mu.edu/InstanceCount.txt" - -#endif - #if USE_SERVER_LOCK_FILE // Name of server lock file shared by sibling clients running with a shared working directory @@ -1608,54 +1596,6 @@ fprintf(fp,"%s %s\n",tsb, s); fclose(fp); } -// Get the Instance Count of the server process - -#if NO_SERVER || (!USE_SERVER_INSTANCE_COUNTS) - -int getServerInstanceCount() -{ -return 0; -} - -#else - -int getServerInstanceCount() -{ -// Pre-empty the response file so it does not end up with any misleading content from a previous command if the -// current command fails. - -FILE *fp = fopen(SERVER_RESPONSE_FILE_NAME,"wt"); -if (fp==NULL) - { - printf("Error: Unable to write to server response file %s\n",SERVER_RESPONSE_FILE_NAME); - exit(EXIT_FAILURE); - }; -fclose(fp); - -size_t ulen = strlen(URL_UTILITY); -size_t slen = strlen(IC_URL); -size_t flen = strlen(SERVER_RESPONSE_FILE_NAME); -size_t len = ulen+slen+flen+10; -char *cmd; -CHECK_MEM( cmd = malloc(len*sizeof(char)) ) -sprintf(cmd,"%s \"%s\" > %s",URL_UTILITY,IC_URL,SERVER_RESPONSE_FILE_NAME); -int res = system(cmd); -free(cmd); -if (res!=0) return 1; - -fp = fopen(SERVER_RESPONSE_FILE_NAME,"rt"); -if (fp==NULL) - { - printf("Error: Unable to read server response file %s\n",SERVER_RESPONSE_FILE_NAME); - exit(EXIT_FAILURE); - }; -if (fscanf(fp,"%d",&res)!=1) res=1; -fclose(fp); -return res; -} - -#endif - // Process response from server static size_t write_curl_data(void *ptr, size_t size, size_t nmemb, void *stream) @@ -1683,16 +1623,6 @@ int sendServerCommand(const char *command) sleepUntilSiblingsFreeServer(); -// Maybe wait for server instance count to drop to zero - -while (TRUE) - { - int ic = getServerInstanceCount(); - if (ic==0) break; - logString("Waiting for server to be free"); - sleepForSecs(ic + rand() % VAR_TIME_BETWEEN_SERVER_CHECKINS); - }; - // Pre-empty the response file so it does not end up with any misleading content from a previous command if the // current command fails. From 344ee6996c341ffb5edecbee9abed1b1005a024b Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Fri, 10 May 2019 18:28:39 +0100 Subject: [PATCH 3/6] msys2 build script and batch file to run standalone exe --- DistributedChaffinMethod/Superperm.bat | 2 ++ DistributedChaffinMethod/msysbuild.sh | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 DistributedChaffinMethod/Superperm.bat create mode 100644 DistributedChaffinMethod/msysbuild.sh diff --git a/DistributedChaffinMethod/Superperm.bat b/DistributedChaffinMethod/Superperm.bat new file mode 100644 index 0000000..3385f48 --- /dev/null +++ b/DistributedChaffinMethod/Superperm.bat @@ -0,0 +1,2 @@ +@echo off +DistributedChaffinMethod team Windows diff --git a/DistributedChaffinMethod/msysbuild.sh b/DistributedChaffinMethod/msysbuild.sh new file mode 100644 index 0000000..fb129e4 --- /dev/null +++ b/DistributedChaffinMethod/msysbuild.sh @@ -0,0 +1,2 @@ +#!/bin/sh +gcc DistributedChaffinMethod.o -lcurl -o DistributedChaffinMethod -fno-pie -no-pie From bcb9a7cf1df17c019366774aaf550b95712999fc Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Fri, 10 May 2019 19:37:25 +0200 Subject: [PATCH 4/6] Link against libcurl --- DistributedChaffinMethod/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/DistributedChaffinMethod/Makefile b/DistributedChaffinMethod/Makefile index 9bd2fc6..9c8e7f5 100644 --- a/DistributedChaffinMethod/Makefile +++ b/DistributedChaffinMethod/Makefile @@ -1,5 +1,6 @@ CC=gcc CFLAGS = -O3 +LDLIBS=-lcurl all: DistributedChaffinMethod From 6e1a56eac37da338968fe1b79075cac73161643d Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Fri, 10 May 2019 18:39:44 +0100 Subject: [PATCH 5/6] Remove unnecessary build command --- DistributedChaffinMethod/msysbuild.sh | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 DistributedChaffinMethod/msysbuild.sh diff --git a/DistributedChaffinMethod/msysbuild.sh b/DistributedChaffinMethod/msysbuild.sh deleted file mode 100644 index fb129e4..0000000 --- a/DistributedChaffinMethod/msysbuild.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -gcc DistributedChaffinMethod.o -lcurl -o DistributedChaffinMethod -fno-pie -no-pie From 402b14a892a23bc4a2f94bc4cdc6cec16e0ace67 Mon Sep 17 00:00:00 2001 From: Mike Bell Date: Fri, 10 May 2019 20:20:54 +0100 Subject: [PATCH 6/6] Reinstate getServerInstanceCount as that was calling curl directly --- .../DistributedChaffinMethod.c | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/DistributedChaffinMethod/DistributedChaffinMethod.c b/DistributedChaffinMethod/DistributedChaffinMethod.c index d7204c6..a07da20 100644 --- a/DistributedChaffinMethod/DistributedChaffinMethod.c +++ b/DistributedChaffinMethod/DistributedChaffinMethod.c @@ -76,6 +76,10 @@ another instance of the program. // Constants // --------- +// Choose whether to use an "InstanceCount" file on the server to avoid running more than one PHP process at once + +#define USE_SERVER_INSTANCE_COUNTS FALSE + // Choose whether to use a "server lock" file on the client computer to coordinate server access between multiple client instances #define USE_SERVER_LOCK_FILE FALSE @@ -89,6 +93,14 @@ another instance of the program. #define SERVER_URL "http://ada.mscsnet.mu.edu/ChaffinMethod.php?version=9&" +#if USE_SERVER_INSTANCE_COUNTS + +// URL for InstanceCount file + + #define IC_URL "http://ada.mscsnet.mu.edu/InstanceCount.txt" + +#endif + #if USE_SERVER_LOCK_FILE // Name of server lock file shared by sibling clients running with a shared working directory @@ -1596,6 +1608,70 @@ fprintf(fp,"%s %s\n",tsb, s); fclose(fp); } +// Get the Instance Count of the server process + +#if NO_SERVER || (!USE_SERVER_INSTANCE_COUNTS) + +int getServerInstanceCount() +{ +return 0; +} + +#else + +int read_instance_count_data(void *ptr, size_t size, size_t nmemb, void *pInstanceCount) +{ + char buffer[12]; + size_t slen = 11; + if (size * nmemb < 11) slen = size * nmemb; + memcpy(buffer, ptr, slen); + buffer[slen] = 0; + int* pIntInstanceCount = (int*)pInstanceCount; + if (sscanf(buffer, "%d", pIntInstanceCount) != 1) + { + *pIntInstanceCount = 1; + } +} + +int getServerInstanceCount() +{ +int instanceCount = 1; + +CURL *curl; +CURLcode res; + +curl_global_init(CURL_GLOBAL_ALL); + +/* init the curl session */ +curl = curl_easy_init(); + +curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl/7.60.0"); + +/* set URL to get here */ +curl_easy_setopt(curl, CURLOPT_URL, IC_URL); + +/* disable progress meter, set to 0L to enable and disable debug output */ +curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + +/* send all data to this function */ +curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, read_instance_count_data); + +/* save the instance count */ +curl_easy_setopt(curl, CURLOPT_WRITEDATA, &instanceCount); + +/* get it! */ +res = curl_easy_perform(curl); + +/* cleanup curl stuff */ +curl_easy_cleanup(curl); + +curl_global_cleanup(); + +return instanceCount; +} + +#endif + // Process response from server static size_t write_curl_data(void *ptr, size_t size, size_t nmemb, void *stream) @@ -1623,6 +1699,16 @@ int sendServerCommand(const char *command) sleepUntilSiblingsFreeServer(); +// Maybe wait for server instance count to drop to zero + +while (TRUE) + { + int ic = getServerInstanceCount(); + if (ic==0) break; + logString("Waiting for server to be free"); + sleepForSecs(ic + rand() % VAR_TIME_BETWEEN_SERVER_CHECKINS); + }; + // Pre-empty the response file so it does not end up with any misleading content from a previous command if the // current command fails.