diff lib/misc.c @ 1:8b1883341c6f

Initial revision
author masneyb
date Mon, 05 Aug 2002 19:46:57 +0000
parents
children cd2e26a69461
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/misc.c	Mon Aug 05 19:46:57 2002 +0000
@@ -0,0 +1,963 @@
+/*****************************************************************************/
+/*  misc.c - general purpose routines                                        */
+/*  Copyright (C) 1998-2002 Brian Masney <masneyb@gftp.org>                  */
+/*                                                                           */
+/*  This program is free software; you can redistribute it and/or modify     */
+/*  it under the terms of the GNU General Public License as published by     */
+/*  the Free Software Foundation; either version 2 of the License, or        */
+/*  (at your option) any later version.                                      */
+/*                                                                           */
+/*  This program is distributed in the hope that it will be useful,          */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
+/*  GNU General Public License for more details.                             */
+/*                                                                           */
+/*  You should have received a copy of the GNU General Public License        */
+/*  along with this program; if not, write to the Free Software              */
+/*  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA      */
+/*****************************************************************************/
+
+#include "gftp.h"
+#include "options.h"
+
+char *
+insert_commas (unsigned long number, char *dest_str, size_t dest_len)
+{
+  char *frompos, *topos, src[50], *dest;
+  int len, num, rem, i;
+
+  if (dest_str != NULL)
+    *dest_str = '\0';
+  len = log10 (number) + 1;
+
+  if (len <= 0) 
+    {
+      if (dest_str != NULL)
+        strncpy (dest_str, "0", dest_len);
+      else
+        dest_str = g_strconcat ("0", NULL);
+      return (dest_str);
+    }
+
+  len += len / 3;
+  if (dest_str != NULL && len > dest_len)
+    {
+      
+      for (i=0; i<dest_len - 1; i++)
+        dest_str[i] = 'X';
+      dest_str[dest_len - 1] = '\0';
+      return (dest_str);
+    }
+
+  if (dest_str == NULL)
+    dest = g_malloc0 (len);
+  else
+    dest = dest_str;
+
+  g_snprintf (src, sizeof (src), "%ld", number);
+
+  num = strlen (src) / 3 - 1;
+  rem = strlen (src) % 3;
+  frompos = src;
+  topos = dest;
+  for (i = 0; i < rem; i++)
+    *topos++ = *frompos++;
+
+  if (*frompos != '\0')
+    {
+      if (rem != 0)
+	*topos++ = ',';
+      while (num > 0)
+	{
+	  for (i = 0; i < 3; i++)
+	    *topos++ = *frompos++;
+	  *topos++ = ',';
+	  num--;
+	}
+      for (i = 0; i < 3; i++)
+	*topos++ = *frompos++;
+    }
+  *topos = '\0';
+  return (dest);
+}
+
+
+long
+file_countlf (int filefd, long endpos)
+{
+  char tempstr[255];
+  long num, mypos;
+  ssize_t n;
+  int i;
+
+  mypos = num = 0;
+  lseek (filefd, 0, SEEK_SET);
+  while ((n = read (filefd, tempstr, sizeof (tempstr))) > 0)
+    {
+      for (i = 0; i < n; i++)
+	{
+	  if ((tempstr[i] == '\n') && (i > 0) && (tempstr[i - 1] != '\r')
+	      && (endpos == 0 || mypos + i <= endpos))
+	    ++num;
+	}
+      mypos += n;
+    }
+  lseek (filefd, 0, SEEK_SET);
+  return (num);
+}
+
+
+char *
+alltrim (char *str)
+{
+  char *pos, *newpos;
+  int diff;
+
+  pos = str + strlen (str) - 1;
+  while (pos >= str && *pos == ' ')
+    *pos-- = '\0';
+
+  pos = str;
+  diff = 0;
+  while (*pos++ == ' ')
+    diff++;
+
+  if (diff == 0)
+    return (str);
+
+  pos = str + diff;
+  newpos = str;
+  while (*pos != '\0')
+    *newpos++ = *pos++;
+  *newpos = '\0';
+
+  return (str);
+}
+
+
+char *
+expand_path (const char *src)
+{
+  char *str, *pos, *endpos, *prevpos, *newstr, *tempstr, tempchar;
+  struct passwd *pw;
+
+  pw = NULL;
+  str = g_malloc (strlen (src) + 1);
+  strcpy (str, src);
+
+  if (*str == '~')
+    {
+      if (*(str + 1) == '/' || *(str + 1) == '\0')
+	pw = getpwuid (geteuid ());
+      else
+	{
+          if ((pos = strchr (str, '/')) != NULL)
+	    *pos = '\0';
+
+	  pw = getpwnam (str + 1);
+
+          if (pos != NULL)
+            *pos = '/';
+	}
+    }
+
+  endpos = str;
+  newstr = NULL;
+  while ((pos = strchr (endpos, '/')) != NULL)
+    {
+      pos++;
+      while (*pos == '/')
+        pos++;
+      if ((endpos = strchr (pos, '/')) == NULL)
+	endpos = pos + strlen (pos);
+      tempchar = *endpos;
+      *endpos = '\0';
+      if (strcmp (pos, "..") == 0)
+	{
+	  *(pos - 1) = '\0';
+	  if (newstr != NULL && (prevpos = strrchr (newstr, '/')) != NULL)
+	    *prevpos = '\0';
+	}
+      else if (strcmp (pos, ".") != 0)
+	{
+	  if (newstr == NULL)
+	    newstr = g_strconcat (pos - 1, NULL);
+	  else
+	    {
+	      tempstr = g_strconcat (newstr, pos - 1, NULL);
+	      g_free (newstr);
+	      newstr = tempstr;
+	    }
+	}
+      *endpos = tempchar;
+      if (*endpos == '\0')
+	break;
+      endpos = pos + 1;
+    }
+
+  if (newstr == NULL || *newstr == '\0')
+    {
+      if (newstr != NULL)
+	g_free (newstr);
+      newstr = g_malloc0 (2);
+      *newstr = '/';
+    }
+
+  g_free (str);
+
+  if (pw != NULL)
+    {
+      if ((pos = strchr (newstr, '/')) == NULL)
+	{
+	  str = g_malloc (strlen (pw->pw_dir) + 1);
+	  strcpy (str, pw->pw_dir);
+	}
+      else
+	str = g_strconcat (pw->pw_dir, pos, NULL);
+
+      g_free (newstr);
+      newstr = str;
+    }
+
+  return (newstr);
+}
+
+
+void
+remove_double_slashes (char *string)
+{
+  char *newpos, *oldpos;
+
+  oldpos = newpos = string;
+  while (*oldpos != '\0')
+    {
+      *newpos++ = *oldpos++;
+      if (*oldpos == '\0')
+	break;
+      while (*(newpos - 1) == '/' && *(oldpos) == '/')
+	oldpos++;
+    }
+  *newpos = '\0';
+  if (string[strlen (string) - 1] == '/')
+    string[strlen (string) - 1] = '\0';
+}
+
+
+void
+make_nonnull (char **str)
+{
+  if (*str == NULL)
+    *str = g_malloc0 (1);
+}
+
+
+int
+copyfile (char *source, char *dest)
+{
+  FILE *srcfd, *destfd;
+  char buf[8192];
+  size_t n;
+
+  if ((srcfd = fopen (source, "rb")) == NULL)
+    return (0);
+
+  if ((destfd = fopen (dest, "wb")) == NULL)
+    {
+      fclose (srcfd);
+      return (0);
+    }
+
+  while ((n = fread (buf, 1, sizeof (buf), srcfd)) > 0)
+    fwrite (buf, 1, n, destfd);
+
+  fclose (srcfd);
+  fclose (destfd);
+
+  return (1);
+}
+
+
+int
+gftp_match_filespec (char *filename, char *filespec)
+{
+  char *filepos, *wcpos, *pos, *newpos, search_str[20];
+  size_t len, curlen;
+  
+  if (filename == NULL || *filename == '\0' || 
+      filespec == NULL || *filespec == '\0') 
+    return(1);
+
+  filepos = filename;
+  wcpos = filespec;
+  while(1) 
+    {
+      if (*wcpos == '\0') 
+        return (1);
+      else if (*filepos == '\0') 
+        return(0);
+      else if(*wcpos == '?') 
+        {
+          wcpos++;
+          filepos++;
+        }
+      else if(*wcpos == '*' && *(wcpos+1) == '\0') 
+        return(1);
+      else if(*wcpos == '*') 
+        {
+          len = sizeof (search_str);
+          for (pos = wcpos + 1, newpos = search_str, curlen = 0;
+               *pos != '*' && *pos != '?' && *pos != '\0' && curlen < len;
+               curlen++, *newpos++ = *pos++);
+          *newpos = '\0';
+
+          if ((filepos = strstr (filepos, search_str)) == NULL)
+            return(0);
+          wcpos += curlen + 1;
+          filepos += curlen;
+        }
+      else if(*wcpos++ != *filepos++) 
+        return(0);
+    }
+  return (1);
+}
+
+
+int
+gftp_parse_command_line (int *argc, char ***argv)
+{
+  if (*argc > 1)
+    {
+      if (strcmp (argv[0][1], "--help") == 0 || strcmp (argv[0][1], "-h") == 0)
+	gftp_usage ();
+      else if (strcmp (argv[0][1], "--version") == 0 || strcmp (argv[0][1], "-v") == 0)
+	{
+	  printf ("%s\n", version);
+	  exit (0);
+	}
+    }
+  return (0);
+}
+
+
+void
+gftp_usage (void)
+{
+  printf (_("usage: gftp [[ftp://][user:[pass]@]ftp-site[:port][/directory]]\n"));
+  exit (0);
+}
+
+
+char *
+get_xpm_path (char *filename, int quit_on_err)
+{
+  char *tempstr, *exfile;
+
+  tempstr = g_strconcat (BASE_CONF_DIR, "/", filename, NULL);
+  exfile = expand_path (tempstr);
+  g_free (tempstr);
+  if (access (exfile, F_OK) != 0)
+    {
+      g_free (exfile);
+      tempstr = g_strconcat (SHARE_DIR, "/", filename, NULL);
+      exfile = expand_path (tempstr);
+      g_free (tempstr);
+      if (access (exfile, F_OK) != 0)
+	{
+	  g_free (exfile);
+	  exfile = g_strconcat ("/usr/share/icons/", filename, NULL);
+	  if (access (exfile, F_OK) != 0)
+	    {
+	      g_free (exfile);
+	      if (!quit_on_err)
+		return (NULL);
+	      printf (_("gFTP Error: Cannot find file %s in %s or %s\n"),
+		      filename, SHARE_DIR, BASE_CONF_DIR);
+	      exit (-1);
+	    }
+	}
+    }
+  return (exfile);
+}
+
+
+gint
+string_hash_compare (gconstpointer path1, gconstpointer path2)
+{
+  return (strcmp ((char *) path1, (char *) path2) == 0);
+}
+
+
+guint
+string_hash_function (gconstpointer key)
+{
+  return (((char *) key)[0] + ((char *) key)[1] + ((char *) key)[2]);
+}
+
+
+void
+free_file_list (GList * filelist)
+{
+  gftp_file * tempfle;
+  GList * templist;
+
+  templist = filelist;
+  while (templist != NULL)
+    {
+      tempfle = templist->data;
+      free_fdata (tempfle);
+      templist = templist->next;
+    }
+  g_list_free (filelist);
+}
+
+
+void
+free_fdata (gftp_file * fle)
+{
+  if (fle->file)
+    g_free (fle->file);
+  if (fle->user)
+    g_free (fle->user);
+  if (fle->group)
+    g_free (fle->group);
+  if (fle->attribs)
+    g_free (fle->attribs);
+  if (fle->destfile)
+    g_free (fle->destfile);
+  if (fle->fd)
+    fclose (fle->fd);
+  g_free (fle);
+}
+
+
+gftp_file *
+copy_fdata (gftp_file * fle)
+{
+  gftp_file * newfle;
+
+  newfle = g_malloc0 (sizeof (*newfle));
+  memcpy (newfle, fle, sizeof (*newfle));
+
+  if (fle->file)
+    {
+      newfle->file = g_malloc (strlen (fle->file) + 1);
+      strcpy (newfle->file, fle->file);
+    }
+
+  if (fle->user)
+    {
+      newfle->user = g_malloc (strlen (fle->user) + 1);
+      strcpy (newfle->user, fle->user);
+    }
+
+  if (fle->group)
+    {
+      newfle->group = g_malloc (strlen (fle->group) + 1);
+      strcpy (newfle->group, fle->group);
+    }
+
+  if (fle->attribs)
+    {
+      newfle->attribs = g_malloc (strlen (fle->attribs) + 1);
+      strcpy (newfle->attribs, fle->attribs);
+    }
+
+  if (fle->destfile)
+    {
+      newfle->destfile = g_malloc (strlen (fle->destfile) + 1);
+      strcpy (newfle->destfile, fle->destfile);
+    }
+  return (newfle);
+}
+
+
+void
+swap_socks (gftp_request * dest, gftp_request * source)
+{
+  dest->sockfd = source->sockfd;
+  dest->datafd = source->datafd;
+  dest->sockfd_write = source->sockfd_write;
+  dest->cached = 0;
+  if (!source->always_connected)
+    {
+      source->sockfd = NULL;
+      source->datafd = NULL;
+      source->sockfd_write = NULL;
+      source->cached = 1;
+    }
+}
+
+
+int
+compare_request (gftp_request * request1, gftp_request * request2,
+                 int compare_dirs)
+{
+  char *strarr[3][2];
+  int i, ret;
+
+  ret = 1;
+  if (strcmp (request1->protocol_name, request2->protocol_name) == 0 &&
+      request1->port == request2->port)
+    {
+      strarr[0][0] = request1->hostname;
+      strarr[0][1] = request2->hostname;
+      strarr[1][0] = request1->username;
+      strarr[1][1] = request2->username;
+      if (compare_dirs)
+        {
+          strarr[2][0] = request1->directory;
+          strarr[2][1] = request2->directory;
+        }
+      else
+        strarr[2][0] = strarr[2][1] = "";
+
+      for (i = 0; i < 3; i++)
+        {
+          if ((strarr[i][0] && !strarr[i][1]) ||
+              (!strarr[i][0] && strarr[i][1]))
+            {
+              ret = 0;
+              break;
+            }
+
+          if (strarr[i][0] && strarr[i][1] &&
+              strcmp (strarr[i][0], strarr[i][1]) != 0)
+            {
+              ret = 0;
+              break;
+            }
+        }
+    }
+  else
+    ret = 0;
+  return (ret);
+}
+
+
+void
+free_tdata (gftp_transfer * tdata)
+{
+  if (tdata->statmutex)
+    g_free (tdata->statmutex);
+  if (tdata->structmutex)
+    g_free (tdata->structmutex);
+  if (tdata->fromreq != NULL)
+    gftp_request_destroy (tdata->fromreq);
+  if (tdata->toreq != NULL)
+    gftp_request_destroy (tdata->toreq);
+  free_file_list (tdata->files);
+  g_free (tdata);
+}
+
+
+gftp_request * 
+copy_request (gftp_request * req)
+{
+  gftp_request * newreq;
+
+  newreq = g_malloc0 (sizeof (*newreq));
+  memcpy (newreq, req, sizeof (*newreq));
+
+  if (req->hostname)
+    newreq->hostname = g_strconcat (req->hostname, NULL);
+  if (req->username)
+    newreq->username = g_strconcat (req->username, NULL);
+  if (req->password)
+    newreq->password = g_strconcat (req->password, NULL);
+  if (req->account)
+    newreq->account = g_strconcat (req->account, NULL);
+  if (req->directory)
+    newreq->directory = g_strconcat (req->directory, NULL);
+
+  newreq->url_prefix = NULL;
+  newreq->protocol_name = NULL;
+  newreq->sftpserv_path = NULL;
+  newreq->proxy_config = NULL;
+  newreq->proxy_hostname = NULL;
+  newreq->proxy_username = NULL;
+  newreq->proxy_password = NULL;
+  newreq->proxy_account = NULL;
+  newreq->last_ftp_response = NULL;
+  newreq->last_dir_entry = NULL;
+  newreq->sockfd = NULL;
+  newreq->sockfd_write = NULL;
+  newreq->datafd = NULL;
+  newreq->cachefd = NULL;
+  newreq->hostp = NULL;
+  newreq->protocol_data = NULL;
+  
+  if (req->proxy_config != NULL)
+    newreq->proxy_config = g_strconcat (req->proxy_config, NULL);
+
+  req->init (newreq);
+
+  return (newreq);
+}
+
+
+int
+ptym_open (char *pts_name)
+{
+  int fd;
+
+#ifdef __sgi
+  char *tempstr;
+
+  if ((tempstr = _getpty (&fd, O_RDWR, 0600, 0)) == NULL)
+    return (-1);
+
+  strcpy (pts_name, tempstr);
+  return (fd);
+
+#else /* !__sgi */
+
+#ifdef SYSV
+
+  char *tempstr;
+
+  strcpy (pts_name, "/dev/ptmx");
+  if ((fd = open (pts_name, O_RDWR)) < 0)
+    return (-1);
+
+  if (grantpt (fd) < 0)
+    {
+      close (fd);
+      return (-1);
+    }
+
+  if (unlockpt (fd) < 0)
+    {
+      close (fd);
+      return (-1);
+    }
+
+  if ((tempstr = ptsname (fd)) == NULL)
+    {
+      close (fd);
+      return (-1);
+    }
+
+  strcpy (pts_name, tempstr);
+  return (fd);
+
+#else /* !SYSV */
+
+  char *pos1, *pos2;
+
+  strcpy (pts_name, "/dev/ptyXY");
+  for (pos1 = "pqrstuvwxyzPQRST"; *pos1 != '\0'; pos1++) 
+    {
+      pts_name[8] = *pos1;
+      for (pos2 = "0123456789abcdef"; *pos2 != '\0'; pos2++)
+        {
+          pts_name[9] = *pos2;
+          if ((fd = open (pts_name, O_RDWR)) < 0)
+            continue;
+          pts_name[5] = 't';
+          return (fd);
+        }
+    }
+  return (-1);
+
+#endif
+
+#endif
+
+}
+
+
+int
+ptys_open (int fdm, char *pts_name)
+{
+  int fds;
+
+#if !defined (SYSV) && !defined (__sgi)
+
+  chmod (pts_name, S_IRUSR | S_IWUSR);
+  chown (pts_name, getuid (), -1);
+
+#endif
+
+  if ((fds = open (pts_name, O_RDWR)) < 0)
+    {
+      close (fdm);
+      return (-1);
+    }
+
+#ifdef SYSV
+
+  if (ioctl (fds, I_PUSH, "ptem") < 0)
+    {
+      close (fdm);
+      close (fds);
+      return (-1);
+    }
+
+  if (ioctl (fds, I_PUSH, "ldterm") < 0)
+    {
+      close (fdm);
+      close (fds);
+      return (-1);
+    }
+
+  if (ioctl (fds, I_PUSH, "ttcompat") < 0)
+    {
+      close (fdm);
+      close (fds);
+      return (-1);
+    }
+
+#endif
+
+#if !defined(SYSV) && !defined (__sgi) && defined(TIOCSCTTY) && !defined(CIBAUD)
+
+  if (ioctl (fds, TIOCSCTTY, (char *) 0) < 0)
+    {
+      close (fdm);
+      return (-1);
+    }
+
+#endif
+
+  return (fds);
+}
+
+
+int
+tty_raw (int fd)
+{
+  struct termios buf;
+
+  if (tcgetattr (fd, &buf) < 0)
+    return (-1);
+
+  buf.c_iflag |= IGNPAR;
+  buf.c_iflag &= ~(ICRNL | ISTRIP | IXON | IGNCR | IXANY | IXOFF | INLCR);
+  buf.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
+#ifdef IEXTEN
+  buf.c_lflag &= ~(IEXTEN);
+#endif
+
+  buf.c_oflag &= ~(OPOST);
+  buf.c_cc[VMIN] = 1;
+  buf.c_cc[VTIME] = 0;
+
+  if (tcsetattr (fd, TCSADRAIN, &buf) < 0)
+    return (-1);
+  return (0);
+}
+
+
+/* We have the caller send us a pointer to a string so we can write the port
+   into it. It makes it easier so we don't have to worry about freeing it 
+   later on, the caller can just send us an auto variable, The string
+   should be at least 6 chars. I know this is messy... */
+
+char **
+make_ssh_exec_args (gftp_request * request, char *execname, 
+                    int use_sftp_subsys, char *portstring)
+{
+  char **args, *oldstr, *tempstr;
+  int i, j;
+
+  args = g_malloc (sizeof (char *) * (num_ssh_extra_params + 10));
+
+  args[0] = ssh_prog_name != NULL && *ssh_prog_name != '\0' ? 
+            ssh_prog_name : "ssh";
+  i = 1;
+  tempstr = g_strconcat (args[0], NULL);
+
+  if (ssh_extra_params_list != NULL)
+    {
+      for (j=0; ssh_extra_params_list[j] != NULL; j++)
+        {
+          oldstr = tempstr;
+          args[i++] = ssh_extra_params_list[j];
+          tempstr = g_strconcat (oldstr, " ", ssh_extra_params_list[j], NULL);
+          g_free (oldstr);
+        }
+    }
+
+  oldstr = tempstr;
+  tempstr = g_strconcat (oldstr, " -e none", NULL);
+  g_free (oldstr);
+  args[i++] = "-e";
+  args[i++] = "none";
+
+  if (request->username && *request->username != '\0')
+    {
+      oldstr = tempstr;
+      tempstr = g_strconcat (oldstr, " -l ", request->username, NULL);
+      g_free (oldstr);
+      args[i++] = "-l";
+      args[i++] = request->username;
+    }
+
+  if (request->port != 0)
+    {
+      g_snprintf (portstring, 6, "%d", request->port);
+      oldstr = tempstr;
+      tempstr = g_strconcat (oldstr, " -p ", portstring, NULL);
+      g_free (oldstr);
+      args[i++] = "-p";
+      args[i++] = portstring;
+    }
+
+  if (use_sftp_subsys)
+    {
+      oldstr = tempstr;
+      tempstr = g_strconcat (oldstr, " ", request->hostname, " -s sftp", NULL);
+      g_free (oldstr);
+      args[i++] = request->hostname;
+      args[i++] = "-s";
+      args[i++] = "sftp";
+      args[i] = NULL;
+    }
+  else
+    {
+      oldstr = tempstr;
+      tempstr = g_strconcat (oldstr, " ", request->hostname, " \"", execname, 
+                             "\"", NULL);
+      g_free (oldstr);
+      args[i++] = request->hostname;
+      args[i++] = execname;
+      args[i] = NULL;
+    }
+
+  request->logging_function (gftp_logging_misc, request->user_data, 
+                             _("Running program %s\n"), tempstr);
+  g_free (tempstr);
+  return (args);
+}
+
+
+char *
+ssh_start_login_sequence (gftp_request * request, int fd)
+{
+  size_t rem, len, diff, lastdiff;
+  int flags, wrotepw, ok;
+  struct timeval tv;
+  char *tempstr;
+  fd_set rdfds;
+  ssize_t rd;
+
+  rem = len = 100;
+  tempstr = g_malloc0 (len);
+  diff = lastdiff = 0;
+  wrotepw = 0;
+  ok = 1;
+
+  if ((flags = fcntl (fd, F_GETFL, 0)) < 0) 
+    {
+      g_free (tempstr);
+      return (NULL);
+    }
+
+  if (fcntl (fd, F_SETFL, flags | O_NONBLOCK) < 0)
+    {
+      g_free (tempstr);
+      return (NULL);
+    }
+
+  while (1)
+    {
+      FD_ZERO (&rdfds);
+      FD_SET (fd, &rdfds);
+      tv.tv_sec = 5;
+      tv.tv_usec = 0;
+      if (select (fd + 1, &rdfds, NULL, NULL, &tv) < 0)
+        {
+          if (errno == EINTR)
+            continue;
+          ok = 0;
+          break;
+        }
+
+      if ((rd = read (fd, tempstr + diff, rem - 1)) < 0)
+        {
+          if (errno == EINTR)
+            continue;
+          ok = 0;
+          break;
+        }
+      else if (rd == 0)
+        { 
+          ok = 0;
+          break;
+        }
+      tempstr[diff + rd] = '\0';
+      rem -= rd;
+      diff += rd;
+      if (rem <= 1)
+        {
+          tempstr = g_realloc (tempstr, len + 100);
+          tempstr[diff] = '\0';
+          request->logging_function (gftp_logging_recv, request->user_data,
+                                     "%s", tempstr + lastdiff);
+          lastdiff = diff;
+          len += 100;
+          rem = 100;
+        }
+
+      if (!wrotepw && 
+          strlen (tempstr) > 11 && strcmp (tempstr + strlen (tempstr) - 10, 
+                                           "password: ") == 0)
+        {
+          wrotepw = 1;
+          write (fd, request->password, strlen (request->password));
+          write (fd, "\n", 1);
+        }
+
+      else if (!wrotepw && 
+               (strstr (tempstr, "Enter passphrase for RSA key") != NULL ||
+               strstr (tempstr, "Enter passphrase for key '") != NULL))
+        {
+          wrotepw = 1;
+          write (fd, request->password, strlen (request->password));
+          write (fd, "\n", 1);
+        }
+      else if (strlen (tempstr) >= 5 && 
+               strcmp (tempstr + strlen (tempstr) - 5, "xsftp") == 0)
+        break;
+    }
+
+  tempstr[diff] = '\0';
+  request->logging_function (gftp_logging_recv, request->user_data,
+                             "%s\n", tempstr + lastdiff);
+
+  if (ok && fcntl (fd, F_SETFL, flags) < 0)
+    ok = 0;
+
+  if (!ok)
+    {
+      g_free (tempstr);
+      return (NULL);
+    }
+ 
+  return (tempstr);
+}
+
+
+#ifdef G_HAVE_GINT64
+
+gint64
+hton64 (gint64 val)
+{
+  gint64 num;
+  char *pos;
+
+  num = 0;
+  pos = (char *) &num;
+  pos[0] = (val >> 56) & 0xff;
+  pos[1] = (val >> 48) & 0xff;
+  pos[2] = (val >> 40) & 0xff;
+  pos[3] = (val >> 32) & 0xff;
+  pos[4] = (val >> 24) & 0xff;
+  pos[5] = (val >> 16) & 0xff;
+  pos[6] = (val >> 8) & 0xff;
+  pos[7] = val & 0xff;
+  return (num);
+}
+
+#endif
+