tFirst attempt using libcurl to connect to metaserver - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 8b75b68f07617cbf489a17154c034c0e53353469
(DIR) parent e7209ec919eb016fb80517108c65feb26a3d5179
(HTM) Author: Ben Webb <ben@salilab.org>
Date: Thu, 29 Oct 2020 00:48:46 -0700
First attempt using libcurl to connect to metaserver
Diffstat:
M src/Makefile.am | 2 +-
M src/dopewars.c | 18 +++++-------------
M src/dopewars.h | 5 ++---
M src/message.c | 4 ++--
M src/serverside.c | 148 ++++++++++++++++++++++---------
M src/serverside.h | 2 +-
6 files changed, 119 insertions(+), 60 deletions(-)
---
(DIR) diff --git a/src/Makefile.am b/src/Makefile.am
t@@ -21,7 +21,7 @@ CURSESPORTSUBDIR = cursesport
endif
SUBDIRS = $(GUISUBDIR) $(CURSESSUBDIR) $(GTKPORTSUBDIR) $(CURSESPORTSUBDIR) plugins
-dopewars_LDADD = @GUILIB@ @CURSESLIB@ @GTKPORTLIB@ @CURSESPORTLIB@ @GTK_LIBS@ @LTLIBINTL@ @WNDRES@ @PLUGOBJS@ @PLUGLIBS@ @GLIB_LIBS@
+dopewars_LDADD = @GUILIB@ @CURSESLIB@ @GTKPORTLIB@ @CURSESPORTLIB@ @GTK_LIBS@ @LTLIBINTL@ @WNDRES@ @PLUGOBJS@ @PLUGLIBS@ @GLIB_LIBS@ -lcurl
dopewars_DEPENDENCIES = @GUILIB@ @CURSESLIB@ @GTKPORTLIB@ @CURSESPORTLIB@ @WNDRES@ @PLUGOBJS@
bin_PROGRAMS = dopewars
(DIR) diff --git a/src/dopewars.c b/src/dopewars.c
t@@ -210,12 +210,12 @@ struct BITCH Bitch = {
#ifdef NETWORKING
struct METASERVER MetaServer = {
- FALSE, NULL, 0, NULL, 0, NULL, NULL, NULL,
+ FALSE, NULL, NULL, 0, NULL, NULL,
NULL, FALSE, NULL, NULL, NULL, NULL
};
struct METASERVER DefaultMetaServer = {
- TRUE, "dopewars.sourceforge.net", 80, "", 8080, "/metaserver.php",
+ TRUE, "https://dopewars.sourceforge.io/metaserver.php", "", 8080,
"", "", "dopewars server", FALSE, "", "", "", ""
};
t@@ -277,21 +277,15 @@ struct GLOBALS Globals[] = {
{NULL, &MetaServer.Active, NULL, NULL, NULL, "MetaServer.Active",
N_("TRUE if server should report to a metaserver"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 0},
- {NULL, NULL, NULL, &MetaServer.Name, NULL, "MetaServer.Name",
- N_("Metaserver name to report/get server details to/from"),
+ {NULL, NULL, NULL, &MetaServer.URL, NULL, "MetaServer.URL",
+ N_("Metaserver URL to report/get server details to/from"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 0},
- {&MetaServer.Port, NULL, NULL, NULL, NULL, "MetaServer.Port",
- N_("Port for metaserver communication"),
- NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 65535},
{NULL, NULL, NULL, &MetaServer.ProxyName, NULL, "MetaServer.ProxyName",
N_("Name of a proxy for metaserver communication"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 0},
{&MetaServer.ProxyPort, NULL, NULL, NULL, NULL, "MetaServer.ProxyPort",
N_("Port for communicating with the proxy server"),
NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 65535},
- {NULL, NULL, NULL, &MetaServer.Path, NULL, "MetaServer.Path",
- N_("Path of the script on the metaserver"),
- NULL, NULL, 0, "", NULL, NULL, FALSE, 0, 0},
{NULL, NULL, NULL, &MetaServer.LocalName, NULL, "MetaServer.LocalName",
N_("Preferred hostname of your server machine"), NULL, NULL, 0, "",
NULL, NULL, FALSE, 0, 0},
t@@ -1682,12 +1676,10 @@ void CopyNames(struct NAMES *dest, struct NAMES *src)
void CopyMetaServer(struct METASERVER *dest, struct METASERVER *src)
{
dest->Active = src->Active;
- dest->Port = src->Port;
dest->ProxyPort = src->ProxyPort;
dest->UseSocks = src->UseSocks;
- AssignName(&dest->Name, src->Name);
+ AssignName(&dest->URL, src->URL);
AssignName(&dest->ProxyName, src->ProxyName);
- AssignName(&dest->Path, src->Path);
AssignName(&dest->LocalName, src->LocalName);
AssignName(&dest->Password, src->Password);
AssignName(&dest->Comment, src->Comment);
(DIR) diff --git a/src/dopewars.h b/src/dopewars.h
t@@ -100,11 +100,10 @@ struct SOUNDS {
struct METASERVER {
gboolean Active;
- gchar *Name;
- unsigned Port;
+ gchar *URL;
gchar *ProxyName;
unsigned ProxyPort;
- gchar *Path, *LocalName, *Password, *Comment;
+ gchar *LocalName, *Password, *Comment;
gboolean UseSocks;
gchar *authuser, *authpassword, *proxyuser, *proxypassword;
};
(DIR) diff --git a/src/message.c b/src/message.c
t@@ -435,8 +435,8 @@ gboolean OpenMetaHttpConnection(HttpConnection **conn)
gboolean retval;
query = g_strdup_printf("%s?output=text&getlist=%d",
- MetaServer.Path, METAVERSION);
- retval = OpenHttpConnection(conn, MetaServer.Name, MetaServer.Port,
+ MetaServer.URL, METAVERSION);
+ retval = OpenHttpConnection(conn, MetaServer.URL, 80,
MetaServer.ProxyName, MetaServer.ProxyPort,
"",
UseSocks
(DIR) diff --git a/src/serverside.c b/src/serverside.c
t@@ -28,6 +28,7 @@
#include <string.h>
#include <sys/types.h> /* For size_t etc. */
#include <sys/stat.h>
+#include <curl/curl.h>
#ifdef CYGWIN
#include <windows.h> /* For datatypes such as BOOL */
t@@ -90,7 +91,7 @@ static char *attackquestiontr = N_("AE");
int TerminateRequest, ReregisterRequest, RelogRequest;
int MetaUpdateTimeout;
-int MetaMinTimeout;
+long MetaMinTimeout;
gboolean WantQuit = FALSE;
#ifdef CYGWIN
t@@ -107,7 +108,38 @@ GSList *FirstServer = NULL;
static GScanner *Scanner;
/* Data waiting to be sent to/read from the metaserver */
-HttpConnection *MetaConn = NULL;
+CURLM *MetaConnM = NULL;
+
+struct _MetaServerConnection {
+ CURL *h;
+ gchar *data;
+ size_t data_size;
+ char Terminator; /* Character that separates messages */
+ char StripChar; /* Char that should be removed
+ * from messages */
+};
+
+struct _MetaServerConnection MetaConn;
+
+static size_t MetaConnWriteFunc(void *contents, size_t size, size_t nmemb, void *userp)
+{
+ size_t realsize = size * nmemb;
+ struct _MetaServerConnection *conn = (struct _MetaServerConnection *)userp;
+
+ char *ptr = realloc(conn->data, conn->data_size + realsize + 1);
+ if(ptr == NULL) {
+ /* out of memory! */
+ printf("not enough memory (realloc returned NULL)\n");
+ return 0;
+ }
+
+ conn->data = ptr;
+ memcpy(&(conn->data[conn->data_size]), contents, realsize);
+ conn->data_size += realsize;
+ conn->data[conn->data_size] = 0;
+
+ return realsize;
+}
#endif
/* Handle to the high score file */
t@@ -155,9 +187,9 @@ static void MetaSocketStatus(NetworkBuffer *NetBuf,
#endif
#ifdef NETWORKING
-static gboolean MetaConnectError(HttpConnection *conn)
+static gboolean MetaConnectError(CURL *conn)
{
- GString *errstr;
+/*GString *errstr;
if (!IsHttpError(conn))
return FALSE;
t@@ -165,7 +197,7 @@ static gboolean MetaConnectError(HttpConnection *conn)
g_string_assign_error(errstr, MetaConn->NetBuf.error);
dopelog(1, LF_SERVER, _("Failed to connect to metaserver at %s:%u (%s)"),
MetaServer.Name, MetaServer.Port, errstr->str);
- g_string_free(errstr, TRUE);
+ g_string_free(errstr, TRUE);*/
return TRUE;
}
t@@ -227,7 +259,7 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData,
{
#ifdef NETWORKING
struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE];
- GString *headers, *body;
+ GString *body;
gchar *prstr;
gboolean retval;
int i;
t@@ -246,10 +278,13 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData,
/* If the previous connect hung for so long that it's still active, then
* break the connection before we start a new one */
- if (MetaConn)
- CloseHttpConnection(MetaConn);
+ if (MetaConn.h) {
+ curl_multi_remove_handle(MetaConnM, MetaConn.h);
+ curl_easy_cleanup(MetaConn.h);
+ MetaConn.h = NULL;
+ free(MetaConn.data);
+ }
- headers = g_string_new("");
body = g_string_new("");
g_string_assign(body, "output=text&");
t@@ -284,35 +319,36 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData,
}
}
- g_string_printf(headers,
- "Content-Type: application/x-www-form-urlencoded\n"
- "Content-Length: %d", (int)strlen(body->str));
-
- retval = OpenHttpConnection(&MetaConn, MetaServer.Name, MetaServer.Port,
- MetaServer.ProxyName, MetaServer.ProxyPort,
- BindAddress,
- UseSocks && MetaServer.UseSocks ? &Socks : NULL,
- "POST", MetaServer.Path, headers->str,
- body->str);
- g_string_free(headers, TRUE);
+ MetaConn.h = curl_easy_init();
+ MetaConn.data = malloc(1);
+ MetaConn.Terminator = '\n';
+ MetaConn.StripChar = '\r';
+ MetaConn.data_size = 0;
+ if (MetaConn.h) {
+ int still_running;
+ curl_easy_setopt(MetaConn.h, CURLOPT_COPYPOSTFIELDS, body->str);
+ curl_easy_setopt(MetaConn.h, CURLOPT_URL, MetaServer.URL);
+ curl_easy_setopt(MetaConn.h, CURLOPT_WRITEFUNCTION, MetaConnWriteFunc);
+ curl_easy_setopt(MetaConn.h, CURLOPT_WRITEDATA, &MetaConn);
+
+ curl_multi_add_handle(MetaConnM, MetaConn.h);
+ curl_multi_perform(MetaConnM, &still_running);
+ dopelog(2, LF_SERVER, _("Waiting for connect to metaserver at %s..."),
+ MetaServer.URL);
+ }
g_string_free(body, TRUE);
- if (retval) {
- dopelog(2, LF_SERVER, _("Waiting for connect to metaserver at %s:%u..."),
- MetaServer.Name, MetaServer.Port);
- } else {
- MetaConnectError(MetaConn);
+/* MetaConnectError(MetaConn);
CloseHttpConnection(MetaConn);
MetaConn = NULL;
- return;
- }
- SetHttpAuthFunc(MetaConn, ServerHttpAuth, NULL);
+ return;*/
+/*SetHttpAuthFunc(MetaConn, ServerHttpAuth, NULL);
if (Socks.authuser && Socks.authuser[0] &&
Socks.authpassword && Socks.authpassword[0]) {
SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, ServerNetBufAuth,
NULL);
- }
+ }*/
#ifdef GUI_SERVER
SetNetworkBufferCallBack(&MetaConn->NetBuf, MetaSocketStatus, NULL);
#endif
t@@ -952,7 +988,7 @@ void RequestServerShutdown(void)
*/
gboolean IsServerShutdown(void)
{
- return (WantQuit && !FirstServer && !MetaConn);
+ return (WantQuit && !FirstServer && !MetaConn.h);
}
static GPrintFunc StartServerReply(NetworkBuffer *netbuf)
t@@ -1182,6 +1218,9 @@ void ServerLoop(struct CMDLINE *cmdline)
InitConfiguration(cmdline);
+ curl_global_init(CURL_GLOBAL_DEFAULT);
+ MetaConnM = curl_multi_init();
+
if (!StartServer())
return;
t@@ -1207,9 +1246,10 @@ void ServerLoop(struct CMDLINE *cmdline)
FD_ZERO(&readfs);
FD_ZERO(&writefs);
FD_ZERO(&errorfs);
+ curl_multi_fdset(MetaConnM, &readfs, &writefs, &errorfs, &topsock);
FD_SET(ListenSock, &readfs);
FD_SET(ListenSock, &errorfs);
- topsock = ListenSock + 1;
+ topsock = MAX(topsock + 1, ListenSock + 1);
#ifndef CYGWIN
if (localsock >= 0) {
FD_SET(localsock, &readfs);
t@@ -1223,10 +1263,6 @@ void ServerLoop(struct CMDLINE *cmdline)
&topsock);
}
#endif
- if (MetaConn) {
- SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfs, &writefs,
- &errorfs, &topsock);
- }
for (list = FirstServer; list; list = g_slist_next(list)) {
tmp = (Player *)list->data;
if (!IsCop(tmp)) {
t@@ -1311,8 +1347,11 @@ void ServerLoop(struct CMDLINE *cmdline)
if (IsServerShutdown())
break;
#endif
- if (MetaConn) {
- if (RespondToSelect(&MetaConn->NetBuf, &readfs, &writefs,
+ if (MetaConn.h) {
+ int still_running;
+ curl_multi_perform(MetaConnM, &still_running);
+// dopelog(2, LF_SERVER, "MetaServer multi_perform: %d", still_running);
+/* if (RespondToSelect(&MetaConn->NetBuf, &readfs, &writefs,
&errorfs, &DoneOK)) {
while ((buf = ReadHttpResponse(MetaConn, &DoneOK))) {
gboolean ReadingBody = (MetaConn->Status == HS_READBODY);
t@@ -1331,6 +1370,30 @@ void ServerLoop(struct CMDLINE *cmdline)
MetaConn = NULL;
if (IsServerShutdown())
break;
+ } */
+ if (still_running == 0) {
+ char *ch = MetaConn.data;
+ while(ch && *ch) {
+ char *sep_pt = strchr(ch, MetaConn.Terminator);
+ if (sep_pt) {
+ *sep_pt = '\0';
+ if (sep_pt > ch && sep_pt[-1] == MetaConn.StripChar) {
+ sep_pt[-1] = '\0';
+ }
+ sep_pt++;
+ }
+ if (*ch) {
+ dopelog(2, LF_SERVER, "MetaServer: %s", ch);
+ }
+ ch = sep_pt;
+ }
+ dopelog(4, LF_SERVER, "MetaServer: (closed)\n");
+ curl_multi_remove_handle(MetaConnM, MetaConn.h);
+ curl_easy_cleanup(MetaConn.h);
+ MetaConn.h = NULL;
+ free(MetaConn.data);
+ if (IsServerShutdown())
+ break;
}
}
t@@ -1365,6 +1428,10 @@ void ServerLoop(struct CMDLINE *cmdline)
#endif
StopServer();
g_string_free(LineBuf, TRUE);
+
+ curl_multi_cleanup(MetaConnM);
+
+ curl_global_cleanup();
}
#ifdef GUI_SERVER
t@@ -3703,7 +3770,7 @@ void ClearFightTimeout(Player *Play)
* unless "mintime" is already smaller (as long as it's not -1, which
* means "uninitialized"). Returns 1 if the timeout has already expired.
*/
-int AddTimeout(time_t timeout, time_t timenow, int *mintime)
+long AddTimeout(time_t timeout, time_t timenow, long *mintime)
{
if (timeout == 0)
return 0;
t@@ -3721,14 +3788,15 @@ int AddTimeout(time_t timeout, time_t timenow, int *mintime)
* an event has already expired, returns 0. If no events are pending,
* returns -1. "First" should point to a list of valid players.
*/
-int GetMinimumTimeout(GSList *First)
+long GetMinimumTimeout(GSList *First)
{
Player *Play;
GSList *list;
- int mintime = -1;
+ long mintime = -1;
time_t timenow;
timenow = time(NULL);
+ curl_multi_timeout(MetaConnM, &mintime);
if (AddTimeout(MetaMinTimeout, timenow, &mintime))
return 0;
if (AddTimeout(MetaUpdateTimeout, timenow, &mintime))
(DIR) diff --git a/src/serverside.h b/src/serverside.h
t@@ -52,7 +52,7 @@ int LoseBitch(Player *Play, Inventory *Guns, Inventory *Drugs);
void GainBitch(Player *Play);
void SetFightTimeout(Player *Play);
void ClearFightTimeout(Player *Play);
-int GetMinimumTimeout(GSList *First);
+long GetMinimumTimeout(GSList *First);
GSList *HandleTimeouts(GSList *First);
void ConvertHighScoreFile(const gchar *convertfile);
void OpenHighScoreFile(void);