tUse GError for curl error handling - 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 826c6ac4c313c45fad652728ea9002483507ef9a
 (DIR) parent a2b557a74595793a733876f6164e1cce5df1e3a2
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Mon,  2 Nov 2020 23:11:28 -0800
       
       Use GError for curl error handling
       
       Diffstat:
         M src/curses_client/curses_client.c   |      14 +++++++-------
         M src/gui_client/newgamedia.c         |      23 ++++++-----------------
         M src/message.c                       |       8 ++++----
         M src/message.h                       |       2 +-
         M src/network.c                       |      86 ++++++++++++++++++++-----------
         M src/network.h                       |      12 ++++++++++--
         M src/serverside.c                    |      29 ++++++++++++-----------------
       
       7 files changed, 97 insertions(+), 77 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -367,7 +367,7 @@ static void SelectServerManually(void)
        static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
        {
          int c;
       -  const char *merr;
       +  GError *tmp_error = NULL;
          GSList *ListPt;
          ServerData *ThisServer;
          GString *text;
       t@@ -381,8 +381,9 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
          mvaddstr(top + 1, 1, _("Please wait... attempting to contact metaserver..."));
          refresh();
        
       -  if ((merr = OpenMetaHttpConnection(&MetaConn))) {
       -    g_string_assign(errstr, merr);
       +  if (!OpenMetaHttpConnection(&MetaConn, &tmp_error)) {
       +    g_string_assign(errstr, tmp_error->message);
       +    g_error_free(tmp_error);
            return FALSE;
          }
        
       t@@ -416,12 +417,11 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
              if (c == '\f')
                wrefresh(curscr);
            }
       -    merr = CurlConnectionPerform(&MetaConn, &still_running);
       -    if (merr) {
       -      g_string_assign(errstr, merr);
       +    if (!CurlConnectionPerform(&MetaConn, &still_running, &tmp_error)) {
       +      g_string_assign(errstr, tmp_error->message);
       +      g_error_free(tmp_error);
              return FALSE;
            } else if (still_running == 0) {
       -      GError *tmp_error = NULL;
              if (!HandleWaitingMetaServerData(&MetaConn, &ServerList, &tmp_error)) {
                CloseCurlConnection(&MetaConn);
                g_string_assign(errstr, tmp_error->message);
 (DIR) diff --git a/src/gui_client/newgamedia.c b/src/gui_client/newgamedia.c
       t@@ -498,7 +498,7 @@ static void UpdateMetaServerList(GtkWidget *widget)
        {
          GtkWidget *metaserv;
          gchar *text;
       -  const char *merr;
       +  GError *tmp_error = NULL;
        
          /* Terminate any existing connection attempts */
          ShutdownNetworkBuffer(&stgam.play->NetBuf);
       t@@ -514,23 +514,12 @@ static void UpdateMetaServerList(GtkWidget *widget)
          SetStartGameStatus(text);
          g_free(text);
        
       -  if ((merr = OpenMetaHttpConnection(stgam.MetaConn))) {
       -    ConnectError(TRUE);
       -  } else {
       +  if (!OpenMetaHttpConnection(stgam.MetaConn, &tmp_error)) {
       +    text = g_strdup_printf(_("Status: ERROR: %s"), tmp_error->message);
       +    g_error_free(tmp_error);
       +    SetStartGameStatus(text);
       +    g_free(text);
          }
       -  /*
       -  if (OpenMetaHttpConnection(&stgam.MetaConn)) {
       -    metaserv = stgam.metaserv;
       -    SetHttpAuthFunc(stgam.MetaConn, AuthDialog, NULL);
       -    SetNetworkBufferUserPasswdFunc(&stgam.MetaConn->NetBuf,
       -                                   MetaSocksAuthDialog, NULL);
       -    SetNetworkBufferCallBack(&stgam.MetaConn->NetBuf,
       -                             MetaSocketStatus, NULL);
       -  } else {
       -    ConnectError(TRUE);
       -    CloseHttpConnection(stgam.MetaConn);
       -    stgam.MetaConn = NULL;
       -  }*/
        }
        
        static void MetaServerConnect(GtkWidget *widget, gpointer data)
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -427,16 +427,16 @@ static void MetaAppendError(GString *str, LastError *error)
          }
        }
        
       -const char *OpenMetaHttpConnection(CurlConnection *conn)
       +gboolean OpenMetaHttpConnection(CurlConnection *conn, GError **err)
        {
       -  const char *errstr;
       +  gboolean ret;
          gchar *url;
        
          url = g_strdup_printf("%s?output=text&getlist=%d",
                                MetaServer.URL, METAVERSION);
       -  errstr = OpenCurlConnection(conn, url, NULL);
       +  ret = OpenCurlConnection(conn, url, NULL, err);
          g_free(url);
       -  return errstr;
       +  return ret;
        }
        
        GQuark dope_meta_error_quark(void)
 (DIR) diff --git a/src/message.h b/src/message.h
       t@@ -93,7 +93,7 @@ void QueuePlayerMessageForSend(Player *Play, gchar *data);
        gboolean WritePlayerDataToWire(Player *Play);
        gchar *GetWaitingPlayerMessage(Player *Play);
        
       -const char *OpenMetaHttpConnection(CurlConnection *conn);
       +gboolean OpenMetaHttpConnection(CurlConnection *conn, GError **err);
        gboolean HandleWaitingMetaServerData(CurlConnection *conn, GSList **listpt,
                                             GError **err);
        void ClearServerList(GSList **listpt);
 (DIR) diff --git a/src/network.c b/src/network.c
       t@@ -1257,15 +1257,14 @@ void CurlCleanup(CurlConnection *conn)
          curl_global_cleanup();
        }
        
       -const char *CurlConnectionPerform(CurlConnection *conn, int *still_running)
       +gboolean HandleCurlMultiReturn(CurlConnection *conn, CURLMcode mres,
       +                               GError **err)
        {
       -  CURLMcode mres;
          struct CURLMsg *m;
       -
       -  mres = curl_multi_perform(conn->multi, still_running);
          if (mres != CURLM_OK && mres != CURLM_CALL_MULTI_PERFORM) {
            CloseCurlConnection(conn);
       -    return curl_multi_strerror(mres);
       +    g_set_error_literal(err, DOPE_CURLM_ERROR, mres, curl_multi_strerror(mres));
       +    return FALSE;
          }
        
          do {
       t@@ -1273,14 +1272,45 @@ const char *CurlConnectionPerform(CurlConnection *conn, int *still_running)
            m = curl_multi_info_read(conn->multi, &msgq);
            if (m && m->msg == CURLMSG_DONE && m->data.result != CURLE_OK) {
              CloseCurlConnection(conn);
       -      return curl_easy_strerror(m->data.result);
       +      g_set_error_literal(err, DOPE_CURL_ERROR, m->data.result,
       +                          curl_easy_strerror(m->data.result));
       +      return FALSE;
            }
          } while(m);
          
       -  return NULL;
       +  return TRUE;
        }
        
       -const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body)
       +gboolean CurlConnectionPerform(CurlConnection *conn, int *still_running,
       +                               GError **err)
       +{
       +  CURLMcode mres = curl_multi_perform(conn->multi, still_running);
       +  return HandleCurlMultiReturn(conn, mres, err);
       +}
       +
       +GQuark dope_curl_error_quark(void)
       +{
       +  return g_quark_from_static_string("dope-curl-error-quark");
       +}
       +
       +GQuark dope_curlm_error_quark(void)
       +{
       +  return g_quark_from_static_string("dope-curlm-error-quark");
       +}
       +
       +gboolean CurlEasySetopt1(CURL *curl, CURLoption option, void *arg, GError **err)
       +{
       +  CURLcode res = curl_easy_setopt(curl, option, arg);
       +  if (res == CURLE_OK) {
       +    return TRUE;
       +  } else {
       +    g_set_error_literal(err, DOPE_CURL_ERROR, res, curl_easy_strerror(res));
       +    return FALSE;
       +  }
       +}
       +
       +gboolean OpenCurlConnection(CurlConnection *conn, char *URL, char *body,
       +                            GError **err)
        {
          /* If the previous connect hung for so long that it's still active, then
           * break the connection before we start a new one */
       t@@ -1291,39 +1321,37 @@ const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body)
          if (conn->h) {
            const char *errstr;
            int still_running;
       -    CURLcode res;
            CURLMcode mres;
       -    if (body) {
       -      res = curl_easy_setopt(conn->h, CURLOPT_COPYPOSTFIELDS, body);
       -      if (res != CURLE_OK) return curl_easy_strerror(res);
       +    if (body && !CurlEasySetopt1(conn->h, CURLOPT_COPYPOSTFIELDS, body, err)) {
       +      return FALSE;
       +    }
       +
       +    if (!CurlEasySetopt1(conn->h, CURLOPT_URL, URL, err)
       +        || !CurlEasySetopt1(conn->h, CURLOPT_WRITEFUNCTION, MetaConnWriteFunc,
       +                            err)
       +        || !CurlEasySetopt1(conn->h, CURLOPT_WRITEDATA, conn, err)
       +        || !CurlEasySetopt1(conn->h, CURLOPT_HEADERFUNCTION,
       +                            MetaConnHeaderFunc, err)
       +        || !CurlEasySetopt1(conn->h, CURLOPT_HEADERDATA, conn, err)) {
       +      return FALSE;
            }
       -    res = curl_easy_setopt(conn->h, CURLOPT_URL, URL);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
       -    res = curl_easy_setopt(conn->h, CURLOPT_WRITEFUNCTION, MetaConnWriteFunc);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
       -    res = curl_easy_setopt(conn->h, CURLOPT_WRITEDATA, conn);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
       -    res = curl_easy_setopt(conn->h, CURLOPT_HEADERFUNCTION, MetaConnHeaderFunc);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
       -    res = curl_easy_setopt(conn->h, CURLOPT_HEADERDATA, conn);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
        
            mres = curl_multi_add_handle(conn->multi, conn->h);
            if (mres != CURLM_OK && mres != CURLM_CALL_MULTI_PERFORM) {
       -      return curl_multi_strerror(mres);
       +      g_set_error_literal(err, DOPE_CURLM_ERROR, mres,
       +                          curl_multi_strerror(mres));
       +      return FALSE;
            }
            conn->data = g_malloc(1);
            conn->data_size = 0;
            conn->headers = g_ptr_array_new_with_free_func(g_free);
            conn->running = TRUE;
       -    errstr = CurlConnectionPerform(conn, &still_running);
       -    if (errstr) {
       -      return errstr;
       -    }
       -    return NULL;
       +    return CurlConnectionPerform(conn, &still_running, err);
          } else {
       -    return "Could not init curl";
       +    g_set_error_literal(err, DOPE_CURLM_ERROR, 0, _("Could not init curl"));
       +    return FALSE;
          }
       +  return TRUE;
        }
        
        char *CurlNextLine(CurlConnection *conn, char *ch)
 (DIR) diff --git a/src/network.h b/src/network.h
       t@@ -226,11 +226,19 @@ gchar *ExpandWriteBuffer(ConnBuf *conn, int numbytes, LastError **error);
        void CommitWriteBuffer(NetworkBuffer *NetBuf, ConnBuf *conn, gchar *addpt,
                               guint addlen);
        
       +#define DOPE_CURL_ERROR dope_curl_error_quark()
       +GQuark dope_curl_error_quark(void);
       +
       +#define DOPE_CURLM_ERROR dope_curlm_error_quark()
       +GQuark dope_curlm_error_quark(void);
       +
        void CurlInit(CurlConnection *conn);
        void CurlCleanup(CurlConnection *conn);
       -const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body);
       +gboolean OpenCurlConnection(CurlConnection *conn, char *URL, char *body,
       +                            GError **err);
        void CloseCurlConnection(CurlConnection *conn);
       -const char *CurlConnectionPerform(CurlConnection *conn, int *still_running);
       +gboolean CurlConnectionPerform(CurlConnection *conn, int *still_running,
       +                               GError **err);
        char *CurlNextLine(CurlConnection *conn, char *ch);
        
        gboolean OpenHttpConnection(HttpConnection **conn, gchar *HostName,
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -156,10 +156,10 @@ static void MetaSocketStatus(NetworkBuffer *NetBuf,
        #endif
        
        #ifdef NETWORKING
       -static void MetaConnectError(CurlConnection *conn, const char *errstr)
       +static void MetaConnectError(CurlConnection *conn, GError *err)
        {
          dopelog(1, LF_SERVER, _("Failed to connect to metaserver at %s (%s)"),
       -          MetaServer.URL, errstr);
       +          MetaServer.URL, err->message);
        }
        
        void log_meta_headers(gpointer data, gpointer user_data)
       t@@ -229,7 +229,8 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData,
          struct HISCORE MultiScore[NUMHISCORE], AntiqueScore[NUMHISCORE];
          GString *body;
          gchar *prstr;
       -  const char *errstr;
       +  gboolean ret;
       +  GError *tmp_error = NULL;
          int i;
        
          if (!MetaServer.Active || WantQuit || !Server) {
       t@@ -278,21 +279,15 @@ void RegisterWithMetaServer(gboolean Up, gboolean SendData,
            }
          }
        
       -  errstr = OpenCurlConnection(&MetaConn, MetaServer.URL, body->str);
       +  ret = OpenCurlConnection(&MetaConn, MetaServer.URL, body->str, &tmp_error);
        
          dopelog(2, LF_SERVER, _("Waiting for connect to metaserver at %s..."),
                  MetaServer.URL);
          g_string_free(body, TRUE);
       -  if (errstr) {
       -    MetaConnectError(&MetaConn, errstr);
       +  if (!ret) {
       +    MetaConnectError(&MetaConn, tmp_error);
       +    g_error_free(tmp_error);
          }
       -/*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@@ -1291,11 +1286,11 @@ void ServerLoop(struct CMDLINE *cmdline)
              break;
        #endif
            if (MetaConn.running) {
       +      GError *tmp_error = NULL;
              int still_running;
       -      const char *errstr;
       -      errstr = CurlConnectionPerform(&MetaConn, &still_running);
       -      if (errstr) {
       -        MetaConnectError(&MetaConn, errstr);
       +      if (!CurlConnectionPerform(&MetaConn, &still_running, &tmp_error)) {
       +        MetaConnectError(&MetaConn, tmp_error);
       +        g_error_free(tmp_error);
                if (IsServerShutdown())
                  break;
              } else if (still_running == 0) {