changeset 944:5b681cba67b2

2008-01-24 Brian Masney <masneyb@gftp.org> * lib/gftp.h lib/rfc959.c lib/protocols.c lib/misc.c - don't store the structure from getaddrinfo()/gethostbyname() in the gftp_request structure. Instead, store the address of the current server in a separate pointer.
author masneyb
date Thu, 24 Jan 2008 23:31:26 +0000
parents ca75331d0f82
children 3fb46c737594
files ChangeLog lib/gftp.h lib/misc.c lib/protocols.c lib/rfc959.c
diffstat 5 files changed, 149 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jan 24 23:29:20 2008 +0000
+++ b/ChangeLog	Thu Jan 24 23:31:26 2008 +0000
@@ -1,4 +1,9 @@
 2008-01-24 Brian Masney <masneyb@gftp.org>
+	* lib/gftp.h lib/rfc959.c lib/protocols.c lib/misc.c - don't store
+	the structure from getaddrinfo()/gethostbyname() in the 
+	gftp_request structure. Instead, store the address of the current
+	server in a separate pointer.
+
 	* docs/sample.gftp/gftprc - updated the config file to the current
 	release
 
--- a/lib/gftp.h	Thu Jan 24 23:29:20 2008 +0000
+++ b/lib/gftp.h	Thu Jan 24 23:31:26 2008 +0000
@@ -105,13 +105,6 @@
 #define AF_LOCAL AF_UNIX
 #endif
 
-#ifdef HAVE_GETADDRINFO
-#define HAVE_IPV6
-#define GFTP_GET_AI_FAMILY(request)	((request) != NULL && (request)->hostp != NULL ? (request)->hostp->ai_family : -1)
-#else
-#define GFTP_GET_AI_FAMILY(request)	AF_INET
-#endif
-
 /* Solaris needs this included for major()/minor() */
 #ifdef HAVE_SYS_MKDEV_H
 #include <sys/mkdev.h>
@@ -161,6 +154,10 @@
 # define GFTP_LOG_FUNCTION_ATTRIBUTES
 #endif
 
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
+# define HAVE_IPV6
+#endif
+
 #if defined (_LARGEFILE_SOURCE) && !defined (__hppa__) && !defined (__hppa)
 #define GFTP_OFF_T_HEX_PRINTF_MOD	"%llx"
 #define GFTP_OFF_T_INTL_PRINTF_MOD	"%'lld"
@@ -388,22 +385,15 @@
   int wakeup_main_thread[2];	/* FD that gets written to by the threads
                                    to wakeup the parent */
 
-  /* One of these are used to lookup the IP address of the host we are
-     connecting to */
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  struct addrinfo *hostp,
-                  *current_hostp;
-#else
-  struct hostent host, *hostp;
-  int curhost;
+  void *remote_addr;
+  size_t remote_addr_len;
 #endif
+  int ai_family;
 
-  int ai_family;
   int server_type;		/* The type of server we are connected to.
                                    See GFTP_DIRTYPE_* above */
-  unsigned int free_hostp : 1, 		/* Should we free the hostp structure 
-					   in gftp_destroy_request() */
-               use_proxy : 1,
+  unsigned int use_proxy : 1,
                always_connected : 1,
                need_hostport : 1,
                need_username : 1,
@@ -1023,14 +1013,10 @@
 					  char *proxy_hostname,
 					  unsigned int proxy_port );
 
-#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
-
 struct hostent *r_gethostbyname 	( const char *name, 
 					  struct hostent *result_buf, 
 					  int *h_errnop );
 
-#endif
-
 struct servent *r_getservbyname 	( const char *name, 
 					  const char *proto,
 					  /*@out@*/ struct servent *result_buf, 
--- a/lib/misc.c	Thu Jan 24 23:29:20 2008 +0000
+++ b/lib/misc.c	Thu Jan 24 23:31:26 2008 +0000
@@ -461,6 +461,8 @@
   while (templist != NULL)
     {
       tempfle = templist->data;
+      templist->data = NULL;
+
       gftp_file_destroy (tempfle, 1);
       templist = templist->next;
     }
@@ -488,6 +490,7 @@
   if (fle->destfile)
     newfle->destfile = g_strdup (fle->destfile);
 
+  newfle->user_data = NULL;
   return (newfle);
 }
 
@@ -591,41 +594,26 @@
     newreq->account = g_strdup (req->account);
   if (req->directory)
     newreq->directory = g_strdup (req->directory);
+  if (req->url_prefix)
+    newreq->url_prefix = g_strdup (req->url_prefix);
   newreq->port = req->port;
   newreq->use_proxy = req->use_proxy;
   newreq->logging_function = req->logging_function;
   newreq->ai_family = req->ai_family;
 
-  if (req->hostp)
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
+  if (req->remote_addr == NULL)
     {
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-      struct addrinfo *hostp = req->hostp;
-      struct addrinfo *newhostp = newreq->hostp;
-      
-      while (hostp != NULL)
-        {
-          newhostp = g_malloc (sizeof(struct addrinfo));
-          memcpy (newhostp, hostp, sizeof (struct addrinfo));
-          newhostp->ai_addr = g_malloc (sizeof (struct sockaddr));
-          memcpy(newhostp->ai_addr, hostp->ai_addr, sizeof (struct sockaddr));
-          if (hostp->ai_canonname)
-            newhostp->ai_canonname = strdup(hostp->ai_canonname);
-
-          if (req->current_hostp == hostp)
-            newreq->current_hostp = newhostp;
-
-          hostp = hostp->ai_next; newhostp = newhostp->ai_next;
-        }
-#else
-      newreq->hostp = g_malloc (sizeof (struct hostent));
-      memcpy(newreq->hostp, req->hostp, sizeof (struct hostent));
-      newreq->host = req->host;
-      newreq->curhost = req->curhost;
-#endif
+      newreq->remote_addr = NULL;
+      newreq->remote_addr_len = 0;
     }
   else
-    newreq->hostp = NULL;
-  newreq->free_hostp = 1;
+    {
+      newreq->remote_addr = g_malloc0 (req->remote_addr_len);
+      memcpy (newreq->remote_addr, req->remote_addr, req->remote_addr_len);
+      newreq->remote_addr_len = req->remote_addr_len;
+    }
+#endif
 
   gftp_copy_local_options (&newreq->local_options_vars, 
                            &newreq->local_options_hash,
@@ -942,8 +930,6 @@
 }
 
 
-#if !defined (HAVE_GETADDRINFO) || !defined (HAVE_GAI_STRERROR)
-
 struct hostent *
 r_gethostbyname (const char *name, struct hostent *result_buf, int *h_errnop)
 {
@@ -970,7 +956,6 @@
   return (hent);
 }
 
-#endif /* !HAVE_GETADDRINFO */
 
 struct servent *
 r_getservbyname (const char *name, const char *proto,
@@ -1027,7 +1012,7 @@
   if (slen % 3 > 0)
     num++;
 
-  newstr = g_malloc ((gulong) num * 4 + 1);
+  newstr = g_malloc0 ((gulong) num * 4 + 1);
   newstr[num * 4] = '\0';
   newpos = newstr;
 
@@ -1264,7 +1249,7 @@
   if (strcmp (password, "@EMAIL@") == 0)
     return (g_strdup (password));
 
-  newstr = g_malloc ((gulong) strlen (password) * 2 + 2);
+  newstr = g_malloc0 ((gulong) strlen (password) * 2 + 2);
   newpos = newstr;
   
   *newpos++ = '$';
@@ -1292,7 +1277,7 @@
     return (g_strdup (password));
 
   passwordpos = password + 1;
-  newstr = g_malloc ((gulong) strlen (passwordpos) / 2 + 1);
+  newstr = g_malloc0 ((gulong) strlen (passwordpos) / 2 + 1);
   newpos = newstr;
  
   error = 0;
--- a/lib/protocols.c	Thu Jan 24 23:29:20 2008 +0000
+++ b/lib/protocols.c	Thu Jan 24 23:31:26 2008 +0000
@@ -48,15 +48,9 @@
   if (request->username)
     g_free (request->username);
   if (request->password)
-    {
-      memset (request->password, 0, strlen (request->password));
-      g_free (request->password);
-    }
+    g_free (request->password);
   if (request->account)
-    {
-      memset (request->account, 0, strlen (request->account));
-      g_free (request->account);
-    }
+    g_free (request->account);
   if (request->directory)
     g_free (request->directory);
   if (request->last_ftp_response)
@@ -64,6 +58,11 @@
   if (request->protocol_data)
     g_free (request->protocol_data);
 
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
+  if (request->remote_addr != NULL)
+    g_free (request->remote_addr);
+#endif
+
   if (request->local_options_vars != NULL)
     {
       gftp_config_free_options (request->local_options_vars,
@@ -143,12 +142,6 @@
 {
   g_return_if_fail (request != NULL);
 
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  if (request->free_hostp && request->hostp != NULL)
-    freeaddrinfo (request->hostp);
-#endif
-  request->hostp = NULL;
-
 #ifdef USE_SSL
   if (request->ssl != NULL)
     {
@@ -1164,6 +1157,7 @@
 }
 
 
+/* FIXME - clean up this function */
 static int
 gftp_need_proxy (gftp_request * request, char *service, char *proxy_hostname, 
                  unsigned int proxy_port)
@@ -1177,10 +1171,12 @@
   gint32 netaddr;
   char *pos;
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  struct addrinfo hints;
+  struct addrinfo hints, *hostp;
   unsigned int port;
   int errnum;
   char serv[8];
+#else
+  struct hostent host, *hostp;
 #endif
 
   gftp_lookup_global_option ("dont_use_proxy", &proxy_hosts);
@@ -1191,9 +1187,8 @@
     return (proxy_hostname != NULL && 
             *proxy_hostname != '\0');
 
-  request->hostp = NULL;
+  hostp = NULL;
 #if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
-  request->free_hostp = 1;
   memset (&hints, 0, sizeof (hints));
   hints.ai_flags = AI_CANONNAME;
   hints.ai_family = PF_UNSPEC;
@@ -1209,7 +1204,7 @@
                              _("Looking up %s\n"), request->hostname);
 
   if ((errnum = getaddrinfo (request->hostname, serv, &hints, 
-                             &request->hostp)) != 0)
+                             &hostp)) != 0)
     {
       request->logging_function (gftp_logging_error, request,
                                  _("Cannot look up hostname %s: %s\n"),
@@ -1217,14 +1212,13 @@
       return (GFTP_ERETRYABLE);
     }
 
-  addr = request->hostp->ai_addr;
+  addr = hostp->ai_addr;
 
 #else /* !HAVE_GETADDRINFO */
   request->logging_function (gftp_logging_misc, request,
                              _("Looking up %s\n"), request->hostname);
 
-  if (!(request->hostp = r_gethostbyname (request->hostname, &request->host,
-                                          NULL)))
+  if (!(hostp = r_gethostbyname (request->hostname, &host, NULL)))
     {
       request->logging_function (gftp_logging_error, request,
                                  _("Cannot look up hostname %s: %s\n"),
@@ -1232,7 +1226,7 @@
       return (GFTP_ERETRYABLE);
     }
 
-  addr = (struct sockaddr *) request->host.h_addr_list[0];
+  addr = (struct sockaddr *) host.h_addr_list[0];
 
 #endif /* HAVE_GETADDRINFO */
 
@@ -1286,7 +1280,7 @@
 
   savepos = *endpos;
   *endpos = '\0';
-  *dest = g_malloc ((gulong) (endpos - source + 1));
+  *dest = g_malloc0 ((gulong) (endpos - source + 1));
   strcpy (*dest, source);
   *endpos = savepos;
 
@@ -1917,7 +1911,7 @@
       fle = g_malloc0 (sizeof (*fle));
       while (gftp_get_next_file (request, NULL, fle) > 0)
         {
-          newsize = g_malloc (sizeof (*newsize));
+          newsize = g_malloc0 (sizeof (*newsize));
           *newsize = fle->size;
           g_hash_table_insert (dirhash, fle->file, newsize);
           fle->file = NULL;
@@ -1981,7 +1975,7 @@
       return (NULL);
     }
 
-  fle = g_malloc (sizeof (*fle));
+  fle = g_malloc0 (sizeof (*fle));
   templist = NULL;
   while (gftp_get_next_file (transfer->fromreq, NULL, fle) > 0)
     {
@@ -2345,43 +2339,32 @@
 
   return (port);
 }
-#endif
 
 
 int
-gftp_connect_server (gftp_request * request, char *service,
-                     char *proxy_hostname, unsigned int proxy_port)
+gftp_connect_server_with_getaddr (gftp_request * request, char *service,
+                                  char *proxy_hostname, unsigned int proxy_port)
 {
+  struct addrinfo *hostp, *current_hostp;
   char *connect_host, *disphost;
-  unsigned int port;
-  int sock = -1;
-#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
   struct addrinfo hints, *res;
   intptr_t enable_ipv6;
+  unsigned int port;
+  int ret, sock = -1;
   char serv[8];
-  int errnum;
-
-  if ((errnum = gftp_need_proxy (request, service, proxy_hostname,
+
+  if ((ret = gftp_need_proxy (request, service, proxy_hostname,
                                  proxy_port)) < 0)
-    return (errnum);
+    return (ret);
   else
-    {
-      request->use_proxy = errnum;
-      if (request->use_proxy)
-        request->hostp = NULL;
-    }
+    request->use_proxy = ret;
 
   gftp_lookup_request_option (request, "enable_ipv6", &enable_ipv6);
 
-  request->free_hostp = 1;
   memset (&hints, 0, sizeof (hints));
   hints.ai_flags = AI_CANONNAME;
 
-  if (enable_ipv6)
-    hints.ai_family = PF_UNSPEC;
-  else
-    hints.ai_family = AF_INET;
-
+  hints.ai_family = enable_ipv6 ? PF_UNSPEC : AF_INET;
   hints.ai_socktype = SOCK_STREAM;
 
   if (request->use_proxy)
@@ -2395,27 +2378,24 @@
       port = request->port;
     }
 
-  if (request->hostp == NULL)
+  if (port == 0)
+    strcpy (serv, service); 
+  else
+    snprintf (serv, sizeof (serv), "%d", port);
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Looking up %s\n"), connect_host);
+  if ((ret = getaddrinfo (connect_host, serv, &hints, 
+                             &hostp)) != 0)
     {
-      if (port == 0)
-        strcpy (serv, service); 
-      else
-        snprintf (serv, sizeof (serv), "%d", port);
-
-      request->logging_function (gftp_logging_misc, request,
-                                 _("Looking up %s\n"), connect_host);
-      if ((errnum = getaddrinfo (connect_host, serv, &hints, 
-                                 &request->hostp)) != 0)
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Cannot look up hostname %s: %s\n"),
-                                     connect_host, gai_strerror (errnum));
-          return (GFTP_ERETRYABLE);
-        }
+      request->logging_function (gftp_logging_error, request,
+                                 _("Cannot look up hostname %s: %s\n"),
+                                 connect_host, gai_strerror (ret));
+      return (GFTP_ERETRYABLE);
     }
 
   disphost = connect_host;
-  for (res = request->hostp; res != NULL; res = res->ai_next)
+  for (res = hostp; res != NULL; res = res->ai_next)
     {
       disphost = res->ai_canonname ? res->ai_canonname : connect_host;
       port = get_port (res);
@@ -2443,25 +2423,42 @@
           continue;
         }
 
-      request->current_hostp = res;
+      current_hostp = res;
       request->ai_family = res->ai_family;
       break;
     }
 
   if (res == NULL)
     {
-      if (request->hostp != NULL)
-        {
-          freeaddrinfo (request->hostp);
-          request->hostp = NULL;
-        }
+      if (hostp != NULL)
+        freeaddrinfo (hostp);
+      
       return (GFTP_ERETRYABLE);
     }
 
-#else /* !HAVE_GETADDRINFO */
+  request->remote_addr_len = current_hostp->ai_addrlen;
+  request->remote_addr = g_malloc0 (request->remote_addr_len);
+  memcpy (request->remote_addr, &((struct sockaddr_in *) current_hostp->ai_addr)->sin_addr,
+          request->remote_addr_len);
+
+  request->logging_function (gftp_logging_misc, request,
+                             _("Connected to %s:%d\n"), connect_host, port);
+
+  return (sock);
+}
+#endif
+
+
+int
+gftp_connect_server_legacy (gftp_request * request, char *service,
+                            char *proxy_hostname, unsigned int proxy_port)
+{
   struct sockaddr_in remote_address;
+  char *connect_host, *disphost;
+  struct hostent host, *hostp;
   struct servent serv_struct;
-  int ret;
+  int ret, sock, curhost;
+  unsigned int port;
 
   if ((ret = gftp_need_proxy (request, service, proxy_hostname,
                               proxy_port)) < 0)
@@ -2469,7 +2466,7 @@
 
   request->use_proxy = ret;
   if (request->use_proxy == 1)
-    request->hostp = NULL;
+    hostp = NULL;
 
   request->ai_family = AF_INET;
   if ((sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
@@ -2513,33 +2510,30 @@
 
   remote_address.sin_port = htons (port);
 
-  if (request->hostp == NULL)
+  request->logging_function (gftp_logging_misc, request,
+                             _("Looking up %s\n"), connect_host);
+
+  if (!(hostp = r_gethostbyname (connect_host, &host, NULL)))
     {
-      request->logging_function (gftp_logging_misc, request,
-                                 _("Looking up %s\n"), connect_host);
-      if (!(request->hostp = r_gethostbyname (connect_host, &request->host,
-                                              NULL)))
-        {
-          request->logging_function (gftp_logging_error, request,
-                                     _("Cannot look up hostname %s: %s\n"),
-                                     connect_host, g_strerror (errno));
-          close (sock);
-          return (GFTP_ERETRYABLE);
-        }
+      request->logging_function (gftp_logging_error, request,
+                                 _("Cannot look up hostname %s: %s\n"),
+                                 connect_host, g_strerror (errno));
+      close (sock);
+      return (GFTP_ERETRYABLE);
     }
 
   disphost = NULL;
-  for (request->curhost = 0;
-       request->host.h_addr_list[request->curhost] != NULL;
-       request->curhost++)
+  for (curhost = 0;
+       host.h_addr_list[curhost] != NULL;
+       curhost++)
     {
-      disphost = request->host.h_name;
+      disphost = host.h_name;
       memcpy (&remote_address.sin_addr,
-              request->host.h_addr_list[request->curhost],
-              request->host.h_length);
+              host.h_addr_list[curhost],
+              host.h_length);
       request->logging_function (gftp_logging_misc, request,
                                  _("Trying %s:%d\n"),
-                                 request->host.h_name, port);
+                                 host.h_name, port);
 
       if (connect (sock, (struct sockaddr *) &remote_address,
                    sizeof (remote_address)) == -1)
@@ -2551,25 +2545,42 @@
       break;
     }
 
-  if (request->host.h_addr_list[request->curhost] == NULL)
+  if (host.h_addr_list[curhost] == NULL)
     {
       close (sock);
       return (GFTP_ERETRYABLE);
     }
-#endif /* HAVE_GETADDRINFO */
+
+  return (sock);
+}
+
+
+int
+gftp_connect_server (gftp_request * request, char *service,
+                     char *proxy_hostname, unsigned int proxy_port)
+{
+  int sock;
+
+#if defined (HAVE_GETADDRINFO) && defined (HAVE_GAI_STRERROR)
+  sock = gftp_connect_server_with_getaddr (request, service, proxy_hostname,
+                                           proxy_port);
+#else
+  sock = gftp_connect_server_legacy (request, service, proxy_hostname,
+                                     proxy_port);
+#endif
+
+  if (sock < 0)
+    return (sock);
 
   if (fcntl (sock, F_SETFD, 1) == -1)
     {
       request->logging_function (gftp_logging_error, request,
                                  _("Error: Cannot set close on exec flag: %s\n"),
                                  g_strerror (errno));
-
+      close (sock);
       return (GFTP_ERETRYABLE);
     }
 
-  request->logging_function (gftp_logging_misc, request,
-                             _("Connected to %s:%d\n"), connect_host, port);
-
   if (gftp_fd_set_sockblocking (request, sock, 1) < 0)
     {
       close (sock);
--- a/lib/rfc959.c	Thu Jan 24 23:29:20 2008 +0000
+++ b/lib/rfc959.c	Thu Jan 24 23:31:26 2008 +0000
@@ -767,14 +767,8 @@
                                   &ignore_pasv_address);
       if (ignore_pasv_address)
 	{
-#if defined (HAVE_GETADDRINFO)
-          memcpy (&data_addr.sin_addr,
-                  &((struct sockaddr_in *) request->current_hostp->ai_addr)->sin_addr,
-                  sizeof (data_addr.sin_addr));
-#else
-          memcpy (&data_addr.sin_addr, request->hostp->h_addr_list[request->curhost],
-                  request->hostp->h_length);
-#endif
+          memcpy (&data_addr.sin_addr, request->remote_addr,
+                  request->remote_addr_len);
 
           pos = (char *) &data_addr.sin_addr;
           request->logging_function (gftp_logging_error, request,
@@ -871,7 +865,6 @@
   struct sockaddr_in6 data_addr;
   char *pos, buf[64], *command;
   intptr_t passive_transfer;
-  socklen_t data_addr_len;
   rfc959_parms * parms;
   unsigned int port;
   int resp;
@@ -895,9 +888,8 @@
       return (GFTP_ERETRYABLE);
     }
 
-  data_addr_len = sizeof (data_addr);
   /* This condition shouldn't happen. We better check anyway... */
-  if (data_addr_len != request->current_hostp->ai_addrlen) 
+  if (sizeof (data_addr) != request->remote_addr_len) 
     {
       request->logging_function (gftp_logging_error, request,
 				 _("Error: It doesn't look like we are connected via IPv6. Aborting connection.\n"));
@@ -905,7 +897,7 @@
       return (GFTP_EFATAL);
     }
 
-  memset (&data_addr, 0, data_addr_len);
+  memset (&data_addr, 0, sizeof (data_addr));
   data_addr.sin6_family = AF_INET6;
 
   gftp_lookup_request_option (request, "passive_transfer", &passive_transfer);
@@ -943,11 +935,11 @@
           return (GFTP_EFATAL);
         }
 
-      memcpy (&data_addr, request->current_hostp->ai_addr, data_addr_len);
+      memcpy (&data_addr, request->remote_addr, request->remote_addr_len);
       data_addr.sin6_port = htons (port);
 
       if (connect (parms->data_connection, (struct sockaddr *) &data_addr, 
-                   data_addr_len) == -1)
+                   request->remote_addr_len) == -1)
         {
           request->logging_function (gftp_logging_error, request,
                                     _("Cannot create a data connection: %s\n"),
@@ -958,11 +950,11 @@
     }
   else
     {
-      memcpy (&data_addr, request->current_hostp->ai_addr, data_addr_len);
+      memcpy (&data_addr, request->remote_addr, request->remote_addr_len);
       data_addr.sin6_port = 0;
 
       if (bind (parms->data_connection, (struct sockaddr *) &data_addr, 
-                data_addr_len) == -1)
+                request->remote_addr_len) == -1)
 	{
 	  request->logging_function (gftp_logging_error, request,
 				     _("Cannot bind a port: %s\n"),
@@ -972,7 +964,7 @@
 	}
 
       if (getsockname (parms->data_connection, (struct sockaddr *) &data_addr, 
-                       &data_addr_len) == -1)
+                       &request->remote_addr_len) == -1)
         {
           request->logging_function (gftp_logging_error, request,
 				     _("Cannot get socket name: %s\n"),
@@ -1487,7 +1479,7 @@
 
       if (rsize != size)
         {
-          tempstr = g_malloc (rsize);
+          tempstr = g_malloc0 (rsize);
 
           for (i = 0, j = 0; i < size; i++)
             {