tAdd new curl metaserver support to curses client - 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 8254d96a198d6143bcf74d3005cd61fbc1ac60ee
 (DIR) parent 1ecfd771226f2a0b1b7b0bf64c8e87aae55f608e
 (HTM) Author: Ben Webb <ben@salilab.org>
       Date:   Fri, 30 Oct 2020 23:01:42 -0700
       
       Add new curl metaserver support to curses client
       
       Diffstat:
         M src/curses_client/curses_client.c   |      57 +++++++++++++++++--------------
         M src/message.c                       |     121 +++++++++++++------------------
         M src/message.h                       |       5 ++---
         M src/network.c                       |     141 +++++++++++++++++++++++++++++++
         M src/network.h                       |       7 +++++++
         M src/serverside.c                    |     135 -------------------------------
       
       6 files changed, 233 insertions(+), 233 deletions(-)
       ---
 (DIR) diff --git a/src/curses_client/curses_client.c b/src/curses_client/curses_client.c
       t@@ -61,6 +61,9 @@ static int Width, Depth;
        const static int MaxMessages = 1000;
        
        #ifdef NETWORKING
       +/* Data waiting to be sent to/read from the metaserver */
       +CurlConnection MetaConn;
       +
        static enum {
          CM_SERVER, CM_PROMPT, CM_META, CM_SINGLE
        } ConnectMethod = CM_SERVER;
       t@@ -364,14 +367,13 @@ static void SelectServerManually(void)
        static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
        {
          int c;
       +  const char *merr;
          GSList *ListPt;
          ServerData *ThisServer;
          GString *text;
          gint index;
       -  fd_set readfds, writefds;
       +  fd_set readfds, writefds, errorfds;
          int maxsock;
       -  gboolean DoneOK;
       -  HttpConnection *MetaConn;
          int top = get_ui_area_top();
        
          attrset(TextAttr);
       t@@ -379,25 +381,28 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
          mvaddstr(top + 1, 1, _("Please wait... attempting to contact metaserver..."));
          refresh();
        
       -  if (OpenMetaHttpConnection(&MetaConn)) {
       -    SetHttpAuthFunc(MetaConn, HttpAuthFunc, NULL);
       -    SetNetworkBufferUserPasswdFunc(&MetaConn->NetBuf, SocksAuthFunc, NULL);
       -  } else {
       -    g_string_assign_error(errstr, MetaConn->NetBuf.error);
       -    CloseHttpConnection(MetaConn);
       +  if ((merr = OpenMetaHttpConnection(&MetaConn))) {
       +    g_string_assign(errstr, merr);
            return FALSE;
          }
        
          ClearServerList(&ServerList);
        
       -  do {
       +  while(TRUE) {
       +    long mintime;
       +    struct timeval timeout;
       +    int still_running;
            FD_ZERO(&readfds);
            FD_ZERO(&writefds);
       +    FD_ZERO(&errorfds);
            FD_SET(0, &readfds);
       -    maxsock = 1;
       -    SetSelectForNetworkBuffer(&MetaConn->NetBuf, &readfds, &writefds,
       -                              NULL, &maxsock);
       -    if (bselect(maxsock, &readfds, &writefds, NULL, NULL) == -1) {
       +    curl_multi_fdset(MetaConn.multi, &readfds, &writefds, &errorfds, &maxsock);
       +    curl_multi_timeout(MetaConn.multi, &mintime);
       +    timeout.tv_sec = mintime < 0 ? 5 : mintime;
       +    timeout.tv_usec = 0;
       +    maxsock = MAX(maxsock+1, 1);
       +
       +    if (bselect(maxsock, &readfds, &writefds, &errorfds, &timeout) == -1) {
              if (errno == EINTR) {
                CheckForResize(Play);
                continue;
       t@@ -411,20 +416,20 @@ static gboolean SelectServerFromMetaServer(Player *Play, GString *errstr)
              if (c == '\f')
                wrefresh(curscr);
            }
       -    if (RespondToSelect
       -        (&MetaConn->NetBuf, &readfds, &writefds, NULL, &DoneOK)) {
       -      while (HandleWaitingMetaServerData(MetaConn, &ServerList, &DoneOK)) {
       -      }
       -    }
       -    if (!DoneOK && HandleHttpCompletion(MetaConn)) {
       -      if (IsHttpError(MetaConn)) {
       -        g_string_assign_error(errstr, MetaConn->NetBuf.error);
       -        CloseHttpConnection(MetaConn);
       +    merr = CurlConnectionPerform(&MetaConn, &still_running);
       +    if (merr) {
       +      g_string_assign(errstr, merr);
       +      return FALSE;
       +    } else if (still_running == 0) {
       +      merr = HandleWaitingMetaServerData(&MetaConn, &ServerList);
       +      CloseCurlConnection(&MetaConn);
       +      if (merr) {
       +        g_string_assign(errstr, merr);
                return FALSE;
              }
       +      break;
            }
       -  } while (DoneOK);
       -  CloseHttpConnection(MetaConn);
       +  }
        
          text = g_string_new("");
        
       t@@ -2682,6 +2687,7 @@ void CursesLoop(struct CMDLINE *cmdline)
          BackupConfig();
        
          start_curses();
       +  CurlInit(&MetaConn);
          Width = COLS;
          Depth = LINES;
        
       t@@ -2712,4 +2718,5 @@ void CursesLoop(struct CMDLINE *cmdline)
          } while (c == 'Y');
          FirstClient = RemovePlayer(Play, FirstClient);
          end_curses();
       +  CurlCleanup(&MetaConn);
        }
 (DIR) diff --git a/src/message.c b/src/message.c
       t@@ -427,82 +427,63 @@ static void MetaAppendError(GString *str, LastError *error)
          }
        }
        
       -static ErrorType ETMeta = { MetaAppendError, NULL };
       -
       -gboolean OpenMetaHttpConnection(HttpConnection **conn)
       +const char *OpenMetaHttpConnection(CurlConnection *conn)
        {
       -  gchar *query;
       -  gboolean retval;
       -
       -  query = g_strdup_printf("%s?output=text&getlist=%d",
       -                          MetaServer.URL, METAVERSION);
       -  retval = OpenHttpConnection(conn, MetaServer.URL, 80,
       -                              MetaServer.ProxyName, MetaServer.ProxyPort,
       -                              "",
       -                              UseSocks
       -                              && MetaServer.UseSocks ? &Socks : NULL,
       -                              "GET", query, NULL, NULL);
       -  g_free(query);
       -  return retval;
       +  const char *errstr;
       +  gchar *url;
       +
       +  url = g_strdup_printf("%s?output=text&getlist=%d",
       +                        MetaServer.URL, METAVERSION);
       +  errstr = OpenCurlConnection(conn, url, NULL);
       +  g_free(url);
       +  return errstr;
        }
        
       -gboolean HandleWaitingMetaServerData(HttpConnection *conn,
       -                                     GSList **listpt, gboolean *doneOK)
       +const char *HandleWaitingMetaServerData(CurlConnection *conn, GSList **listpt)
        {
       -  gchar *msg;
       -  ServerData *NewServer;
       -
       -  g_assert(conn && listpt && doneOK);
       -
       -  /* If we're done reading the headers, only read if the data for a whole
       -   * server is available (8 lines) N.B. "Status" is from the _last_ read */
       -  if (conn->Status == HS_READBODY && conn->StatusCode == 200) {
       -    if (CountWaitingMessages(&conn->NetBuf) < 8)
       -      return FALSE;
       -
       -    NewServer = g_new0(ServerData, 1);
       -    NewServer->Name = ReadHttpResponse(conn, doneOK);
       -    msg = ReadHttpResponse(conn, doneOK);
       -    NewServer->Port = atoi(msg);
       -    g_free(msg);
       -    NewServer->Version = ReadHttpResponse(conn, doneOK);
       -    msg = ReadHttpResponse(conn, doneOK);
       -    if (msg[0])
       -      NewServer->CurPlayers = atoi(msg);
       -    else
       -      NewServer->CurPlayers = -1;
       -    g_free(msg);
       -    msg = ReadHttpResponse(conn, doneOK);
       -    NewServer->MaxPlayers = atoi(msg);
       -    g_free(msg);
       -    NewServer->Update = ReadHttpResponse(conn, doneOK);
       -    NewServer->Comment = ReadHttpResponse(conn, doneOK);
       -    NewServer->UpSince = ReadHttpResponse(conn, doneOK);
       -    *listpt = g_slist_append(*listpt, NewServer);
       -  } else if (conn->Status == HS_READSEPARATOR && conn->StatusCode == 200) {
       -    /* This should be the first line of the body, the "MetaServer:" line */
       -    msg = ReadHttpResponse(conn, doneOK);
       -    if (!msg)
       -      return FALSE;
       -    if (strlen(msg) >= 14 && strncmp(msg, "FATAL ERROR:", 12) == 0) {
       -      SetError(&conn->NetBuf.error, &ETMeta, MEC_INTERNAL,
       -               g_strdup(&msg[13]));
       -      *doneOK = FALSE;
       -      return FALSE;
       -    } else if (strncmp(msg, "MetaServer:", 11) != 0) {
       -      SetError(&conn->NetBuf.error, &ETMeta, MEC_BADREPLY, g_strdup(msg));
       -      g_free(msg);
       -      *doneOK = FALSE;
       -      return FALSE;
       +  char *msg;
       +
       +  g_assert(conn && listpt);
       +
       +  msg = conn->data;
       +  /* This should be the first line of the body, the "MetaServer:" line */
       +  if (!msg) return NULL;
       +  if (strlen(msg) >= 14 && strncmp(msg, "FATAL ERROR:", 12) == 0) {
       +          //todo
       +/*  SetError(&conn->NetBuf.error, &ETMeta, MEC_INTERNAL,
       +             g_strdup(&msg[13]));*/
       +  } else if (strncmp(msg, "MetaServer:", 11) != 0) {
       +          //todo
       +/*  SetError(&conn->NetBuf.error, &ETMeta, MEC_BADREPLY, g_strdup(msg));*/
       +  }
       +
       +  msg = CurlNextLine(conn, msg);
       +  while (msg) {
       +    char *name, *port, *version, *curplayers, *maxplayers, *update,
       +         *comment, *upsince;
       +    name = msg;
       +    port = CurlNextLine(conn, name);
       +    version = CurlNextLine(conn, port);
       +    curplayers = CurlNextLine(conn, version);
       +    maxplayers = CurlNextLine(conn, curplayers);
       +    update = CurlNextLine(conn, maxplayers);
       +    comment = CurlNextLine(conn, update);
       +    upsince = CurlNextLine(conn, comment);
       +    msg = CurlNextLine(conn, upsince);
       +    if (msg) {
       +      ServerData *NewServer = g_new0(ServerData, 1);
       +      NewServer->Name = g_strdup(name);
       +      NewServer->Port = atoi(port);
       +      NewServer->Version = g_strdup(version);
       +      NewServer->CurPlayers = curplayers[0] ? atoi(curplayers) : -1;
       +      NewServer->MaxPlayers = atoi(maxplayers);
       +      NewServer->Update = g_strdup(update);
       +      NewServer->Comment = g_strdup(comment);
       +      NewServer->UpSince = g_strdup(upsince);
       +      *listpt = g_slist_append(*listpt, NewServer);
            }
       -    g_free(msg);
       -  } else {
       -    msg = ReadHttpResponse(conn, doneOK);
       -    if (!msg)
       -      return FALSE;
       -    g_free(msg);
          }
       -  return TRUE;
       +  return NULL;
        }
        
        void ClearServerList(GSList **listpt)
 (DIR) diff --git a/src/message.h b/src/message.h
       t@@ -83,9 +83,8 @@ void QueuePlayerMessageForSend(Player *Play, gchar *data);
        gboolean WritePlayerDataToWire(Player *Play);
        gchar *GetWaitingPlayerMessage(Player *Play);
        
       -gboolean OpenMetaHttpConnection(HttpConnection **conn);
       -gboolean HandleWaitingMetaServerData(HttpConnection *conn, GSList **listpt,
       -                                     gboolean *doneOK);
       +const char *OpenMetaHttpConnection(CurlConnection *conn);
       +const char *HandleWaitingMetaServerData(CurlConnection *conn, GSList **listpt);
        void ClearServerList(GSList **listpt);
        #endif /* NETWORKING */
        
 (DIR) diff --git a/src/network.c b/src/network.c
       t@@ -1200,6 +1200,147 @@ static gboolean StartHttpConnect(HttpConnection *conn)
          return TRUE;
        }
        
       +static size_t MetaConnWriteFunc(void *contents, size_t size, size_t nmemb,
       +                                void *userp)
       +{
       +  size_t realsize = size * nmemb;
       +  CurlConnection *conn = (CurlConnection *)userp;
       + 
       +  conn->data = g_realloc(conn->data, conn->data_size + realsize + 1);
       +  memcpy(&(conn->data[conn->data_size]), contents, realsize);
       +  conn->data_size += realsize;
       +  conn->data[conn->data_size] = 0;
       + 
       +  return realsize;
       +}
       +
       +static size_t MetaConnHeaderFunc(char *contents, size_t size, size_t nmemb,
       +                                 void *userp)
       +{
       +  size_t realsize = size * nmemb;
       +  CurlConnection *conn = (CurlConnection *)userp;
       +
       +  gchar *str = g_strchomp(g_strndup(contents, realsize));
       +  g_ptr_array_add(conn->headers, (gpointer)str);
       +  return realsize;
       +}
       +
       +void CurlInit(CurlConnection *conn)
       +{
       +  curl_global_init(CURL_GLOBAL_DEFAULT);
       +  conn->multi = curl_multi_init();
       +  conn->h = curl_easy_init();
       +  conn->running = FALSE;
       +  conn->Terminator = '\n';
       +  conn->StripChar = '\r';
       +  conn->data_size = 0;
       +  conn->headers = NULL;
       +}
       +
       +void CloseCurlConnection(CurlConnection *conn)
       +{
       +  curl_multi_remove_handle(conn->multi, conn->h);
       +  g_free(conn->data);
       +  conn->data_size = 0;
       +  conn->running = FALSE;
       +  g_ptr_array_free(conn->headers, TRUE);
       +  conn->headers = NULL;
       +}
       +
       +void CurlCleanup(CurlConnection *conn)
       +{
       +  if (conn->running) {
       +    CloseCurlConnection(conn);
       +  }
       +  curl_easy_cleanup(conn->h);
       +  curl_multi_cleanup(conn->multi);
       +  curl_global_cleanup();
       +}
       +
       +const char *CurlConnectionPerform(CurlConnection *conn, int *still_running)
       +{
       +  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);
       +  }
       +
       +  do {
       +    int msgq = 0;
       +    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);
       +    }
       +  } while(m);
       +  
       +  return NULL;
       +}
       +
       +const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body)
       +{
       +  /* If the previous connect hung for so long that it's still active, then
       +   * break the connection before we start a new one */
       +  if (conn->running) {
       +    CloseCurlConnection(conn);
       +  }
       +
       +  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);
       +    }
       +    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);
       +    }
       +    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;
       +  } else {
       +    return "Could not init curl";
       +  }
       +}
       +
       +char *CurlNextLine(CurlConnection *conn, char *ch)
       +{
       +  char *sep_pt;
       +  if (!ch) return NULL;
       +  sep_pt = strchr(ch, conn->Terminator);
       +  if (sep_pt) {
       +    *sep_pt = '\0';
       +    if (sep_pt > ch && sep_pt[-1] == conn->StripChar) {
       +      sep_pt[-1] = '\0';
       +    }
       +    sep_pt++;
       +  }
       +  return sep_pt;
       +}
       +
        gboolean OpenHttpConnection(HttpConnection **connpt, gchar *HostName,
                                    unsigned Port, gchar *Proxy,
                                    unsigned ProxyPort, const gchar *bindaddr,
 (DIR) diff --git a/src/network.h b/src/network.h
       t@@ -226,6 +226,13 @@ gchar *ExpandWriteBuffer(ConnBuf *conn, int numbytes, LastError **error);
        void CommitWriteBuffer(NetworkBuffer *NetBuf, ConnBuf *conn, gchar *addpt,
                               guint addlen);
        
       +void CurlInit(CurlConnection *conn);
       +void CurlCleanup(CurlConnection *conn);
       +const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body);
       +void CloseCurlConnection(CurlConnection *conn);
       +const char *CurlConnectionPerform(CurlConnection *conn, int *still_running);
       +char *CurlNextLine(CurlConnection *conn, char *ch);
       +
        gboolean OpenHttpConnection(HttpConnection **conn, gchar *HostName,
                                    unsigned Port, gchar *Proxy,
                                    unsigned ProxyPort, const gchar *bindaddr,
 (DIR) diff --git a/src/serverside.c b/src/serverside.c
       t@@ -109,29 +109,6 @@ CurlConnection MetaConn;
        
        static GScanner *Scanner;
        
       -static size_t MetaConnWriteFunc(void *contents, size_t size, size_t nmemb, void *userp)
       -{
       -  size_t realsize = size * nmemb;
       -  CurlConnection *conn = (CurlConnection *)userp;
       - 
       -  conn->data = g_realloc(conn->data, conn->data_size + realsize + 1);
       -  memcpy(&(conn->data[conn->data_size]), contents, realsize);
       -  conn->data_size += realsize;
       -  conn->data[conn->data_size] = 0;
       - 
       -  return realsize;
       -}
       -
       -static size_t MetaConnHeaderFunc(char *contents, size_t size, size_t nmemb, void *userp)
       -{
       -  size_t realsize = size * nmemb;
       -  CurlConnection *conn = (CurlConnection *)userp;
       -
       -  gchar *str = g_strchomp(g_strndup(contents, realsize));
       -  g_ptr_array_add(conn->headers, (gpointer)str);
       -  return realsize;
       -}
       -
        #endif
        
        /* Handle to the high score file */
       t@@ -185,118 +162,6 @@ static void MetaConnectError(CurlConnection *conn, const char *errstr)
                  MetaServer.URL, errstr);
        }
        
       -void CurlInit(CurlConnection *conn)
       -{
       -  curl_global_init(CURL_GLOBAL_DEFAULT);
       -  conn->multi = curl_multi_init();
       -  conn->h = curl_easy_init();
       -  conn->running = FALSE;
       -  conn->Terminator = '\n';
       -  conn->StripChar = '\r';
       -  conn->data_size = 0;
       -  conn->headers = NULL;
       -}
       -
       -void CloseCurlConnection(CurlConnection *conn)
       -{
       -  curl_multi_remove_handle(conn->multi, conn->h);
       -  g_free(conn->data);
       -  conn->data_size = 0;
       -  conn->running = FALSE;
       -  g_ptr_array_free(conn->headers, TRUE);
       -  conn->headers = NULL;
       -}
       -
       -void CurlCleanup(CurlConnection *conn)
       -{
       -  if (conn->running) {
       -    CloseCurlConnection(conn);
       -  }
       -  curl_easy_cleanup(conn->h);
       -  curl_multi_cleanup(conn->multi);
       -  curl_global_cleanup();
       -}
       -
       -const char *CurlConnectionPerform(CurlConnection *conn, int *still_running)
       -{
       -  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);
       -  }
       -
       -  do {
       -    int msgq = 0;
       -    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);
       -    }
       -  } while(m);
       -  
       -  return NULL;
       -}
       -
       -const char *OpenCurlConnection(CurlConnection *conn, char *URL, char *body)
       -{
       -  /* If the previous connect hung for so long that it's still active, then
       -   * break the connection before we start a new one */
       -  if (conn->running) {
       -    CloseCurlConnection(conn);
       -  }
       -
       -  if (conn->h) {
       -    const char *errstr;
       -    int still_running;
       -    CURLcode res;
       -    CURLMcode mres;
       -    res = curl_easy_setopt(conn->h, CURLOPT_COPYPOSTFIELDS, body);
       -    if (res != CURLE_OK) return curl_easy_strerror(res);
       -    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);
       -    }
       -    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;
       -  } else {
       -    return "Could not init curl";
       -  }
       -}
       -
       -char *CurlNextLine(CurlConnection *conn, char *ch)
       -{
       -  char *sep_pt = strchr(ch, conn->Terminator);
       -  if (sep_pt) {
       -    *sep_pt = '\0';
       -    if (sep_pt > ch && sep_pt[-1] == MetaConn.StripChar) {
       -      sep_pt[-1] = '\0';
       -    }
       -    sep_pt++;
       -  }
       -  return sep_pt;
       -}
       -
        void log_meta_headers(gpointer data, gpointer user_data)
        {
          char *header = data;