Exemple #1
0
static int
_gftpui_common_preserve_perm_time (gftp_transfer * tdata, gftp_file * curfle)
{
  intptr_t preserve_permissions, preserve_time;
  int ret, tmpret;

  gftp_lookup_request_option (tdata->fromreq, "preserve_permissions",
                              &preserve_permissions);
  gftp_lookup_request_option (tdata->fromreq, "preserve_time",
                              &preserve_time);

  ret = 0;
  if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_permissions &&
      curfle->st_mode != 0)
    {
      tmpret = gftp_chmod (tdata->toreq, curfle->destfile,
                           curfle->st_mode & (S_IRWXU | S_IRWXG | S_IRWXO));
      if (tmpret < 0)
        ret = tmpret;
    }

  if (GFTP_IS_CONNECTED (tdata->toreq) && preserve_time &&
      curfle->datetime != 0)
    {
      tmpret = gftp_set_file_time (tdata->toreq, curfle->destfile,
                                   curfle->datetime);
      if (tmpret < 0)
        ret = tmpret;
    }

  if (!GFTP_IS_CONNECTED (tdata->toreq))
    return (ret);
  else
    return (0);
}
Exemple #2
0
static void *
_gftpui_common_thread_callback (void * data)
{ 
  intptr_t network_timeout, sleep_time;
  gftpui_callback_data * cdata;
  struct timespec ts;
  int success;

  cdata = data;
  gftpui_common_num_child_threads++;

  gftp_lookup_request_option (cdata->request, "network_timeout",
                              &network_timeout);
  gftp_lookup_request_option (cdata->request, "sleep_time",
                              &sleep_time);

  success = GFTP_ERETRYABLE;
  while (1)
    {
      if (network_timeout > 0)
        alarm (network_timeout);

      success = cdata->run_function (cdata);
      alarm (0);

      if (cdata->request->cancel)
        {
          cdata->request->logging_function (gftp_logging_error, cdata->request,
                                            _("Operation canceled\n"));
          break;
        }
        
      if (success == GFTP_EFATAL || success == 0 || cdata->retries == 0)
        break;

      cdata->retries--;
      cdata->request->logging_function (gftp_logging_error, cdata->request,
                   _("Waiting %d seconds until trying to connect again\n"),
                   sleep_time);

      ts.tv_sec = sleep_time;
      ts.tv_nsec = 0;
      nanosleep (&ts, NULL);
    }

  cdata->request->stopable = 0;
  gftpui_common_num_child_threads--;

  return (GINT_TO_POINTER (success));
}
Exemple #3
0
static int
fsp_connect (gftp_request * request)
{
  fsp_protocol_data * lpd;
  intptr_t network_timeout;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (request->protonum == GFTP_FSP_NUM, GFTP_EFATAL);

  if(! request->port)
      request->port = gftp_protocol_default_port (request);

  lpd = request->protocol_data;
  lpd->fsp=fsp_open_session(request->hostname, request->port, request->password);

  if(lpd->fsp == NULL)
    return (GFTP_ERETRYABLE);
  /* set up network timeout */
  gftp_lookup_request_option (request, "network_timeout", &network_timeout);
  lpd->fsp->timeout=1000*network_timeout;

  if (!request->directory)
    request->directory = g_strdup ("/");

  request->datafd = lpd->fsp->fd;
  return (0);
}
Exemple #4
0
int
_gftpui_common_do_transfer_file (gftp_transfer * tdata, gftp_file * curfle)
{
  struct timeval updatetime;
  intptr_t trans_blksize;
  ssize_t num_trans;
  char *buf;
  int ret;

  gftp_lookup_request_option (tdata->fromreq, "trans_blksize", &trans_blksize);
  buf = g_malloc0 (trans_blksize);

  memset (&updatetime, 0, sizeof (updatetime));
  gftpui_start_current_file_in_transfer (tdata);

  num_trans = 0;
  while (!tdata->cancel &&
         (num_trans = _do_transfer_block (tdata, curfle, buf,
                                          trans_blksize)) > 0)
    {
      gftp_calc_kbs (tdata, num_trans);

      if (tdata->lasttime.tv_sec - updatetime.tv_sec >= 1 ||
          tdata->curtrans >= tdata->tot_file_trans)
        {
          gftpui_update_current_file_in_transfer (tdata);
          memcpy (&updatetime, &tdata->lasttime, sizeof (updatetime));

          if (tdata->current_file_retries > 0)
            tdata->current_file_retries = 0;
        }
    }

  if (num_trans == GFTP_ENOTRANS)
    num_trans = 0;

  g_free (buf);
  gftpui_finish_current_file_in_transfer (tdata);

  if ((int) num_trans == 0)
    {
      if ((ret = gftp_end_transfer (tdata->fromreq)) < 0)
        return (ret);

      if ((ret = gftp_end_transfer (tdata->toreq)) < 0)
        return (ret);

      tdata->fromreq->logging_function (gftp_logging_misc,
                     tdata->fromreq,
                     _("Successfully transferred %s at %.2f KB/s\n"),
                     curfle->file, tdata->kbs);

      return (0);
    }
  else
    return ((int) num_trans);
}
Exemple #5
0
void
gftpui_protocol_update_timeout (gftp_request * request)
{
  intptr_t network_timeout;

  gftp_lookup_request_option (request, "network_timeout", &network_timeout);

  if (network_timeout > 0)
    alarm (network_timeout);
}
Exemple #6
0
void
gftp_calc_kbs (gftp_transfer * tdata, ssize_t num_read)
{
  /* Needed for systems that size(float) < size(void *) */
  union { intptr_t i; float f; } maxkbs;
  unsigned long waitusecs;
  double start_difftime;
  struct timeval tv;
  int waited;

  gftp_lookup_request_option (tdata->fromreq, "maxkbs", &maxkbs.f);

  if (g_thread_supported ())
    g_static_mutex_lock (&tdata->statmutex);

  gettimeofday (&tv, NULL);

  tdata->trans_bytes += num_read;
  tdata->curtrans += num_read;
  tdata->stalled = 0;

  start_difftime = (tv.tv_sec - tdata->starttime.tv_sec) + ((double) (tv.tv_usec - tdata->starttime.tv_usec) / 1000000.0);

  if (start_difftime <= 0)
    tdata->kbs = tdata->trans_bytes / 1024.0;
  else
    tdata->kbs = tdata->trans_bytes / 1024.0 / start_difftime;

  waited = 0;
  if (maxkbs.f > 0 && tdata->kbs > maxkbs.f)
    {
      waitusecs = num_read / 1024.0 / maxkbs.f * 1000000.0 - start_difftime;

      if (waitusecs > 0)
        {
          if (g_thread_supported ())
            g_static_mutex_unlock (&tdata->statmutex);

          waited = 1;
          usleep (waitusecs);

          if (g_thread_supported ())
            g_static_mutex_lock (&tdata->statmutex);
        }

    }

  if (waited)
    gettimeofday (&tdata->lasttime, NULL);
  else
    memcpy (&tdata->lasttime, &tv, sizeof (tdata->lasttime));

  if (g_thread_supported ())
    g_static_mutex_unlock (&tdata->statmutex);
}
Exemple #7
0
int
gftp_list_files (gftp_request * request)
{
  char *remote_lc_time, *locret;
  int fd;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);

#if ENABLE_NLS
  gftp_lookup_request_option (request, "remote_lc_time", &remote_lc_time);
  if (remote_lc_time != NULL && *remote_lc_time != '\0')
    locret = setlocale (LC_TIME, remote_lc_time);
  else
    locret = setlocale (LC_TIME, NULL);

  if (locret == NULL)
    {
      locret = setlocale (LC_TIME, NULL);
      request->logging_function (gftp_logging_error, request,
                                 _("Error setting LC_TIME to '%s'. Falling back to '%s'\n"),
                                 remote_lc_time, locret);
    }
#else
  locret = _("<unknown>");
#endif

  request->cached = 0;
  if (request->use_cache && (fd = gftp_find_cache_entry (request)) > 0)
    {
      request->logging_function (gftp_logging_misc, request,
                                 _("Loading directory listing %s from cache (LC_TIME=%s)\n"),
                                 request->directory, locret);

      request->cachefd = fd;
      request->cached = 1;
      return (0);
    }
  else if (request->use_cache)
    {
      request->logging_function (gftp_logging_misc, request,
                                 _("Loading directory listing %s from server (LC_TIME=%s)\n"),
                                 request->directory, locret);

      request->cachefd = gftp_new_cache_entry (request);
      request->cached = 0; 
    }

  if (request->list_files == NULL)
    return (GFTP_EFATAL);

  return (request->list_files (request));
}
Exemple #8
0
void
gftp_setup_startup_directory (gftp_request * request, const char *option_name)
{
  char *startup_directory, *tempstr;

  gftp_lookup_request_option (request, option_name, &startup_directory);

  if (*startup_directory != '\0' &&
      (tempstr = gftp_expand_path (request, startup_directory)) != NULL)
    {
      gftp_set_directory (request, tempstr);
      g_free (tempstr);
    }
}
Exemple #9
0
int
gftpui_common_cmd_open (void *uidata, gftp_request * request,
                        void *other_uidata, gftp_request * other_request,
                        const char *command)
{
  gftpui_callback_data * cdata;
  intptr_t retries;

  if (GFTP_IS_CONNECTED (request))
    gftpui_disconnect (uidata);
  
  if (command != NULL)
    {
      if (*command == '\0')
        {
          request->logging_function (gftp_logging_error, request,
                                     _("usage: open " GFTP_URL_USAGE "\n"));
          return (1);
        }
    
      if (gftp_parse_url (request, command) < 0)
        return (1);
    }

  if (gftp_need_username (request))
    gftpui_prompt_username (uidata, request);

  if (gftp_need_password (request))
    gftpui_prompt_password (uidata, request);

  gftp_lookup_request_option (request, "retries", &retries);

  cdata = g_malloc0 (sizeof (*cdata));
  cdata->request = request;
  cdata->uidata = uidata;
  cdata->run_function = gftpui_common_run_connect;
  cdata->retries = retries;
  cdata->dont_check_connection = 1;

  if (request->refreshing)
    cdata->dont_refresh = 1;

  gftpui_show_busy (TRUE);
  gftpui_common_run_callback_function (cdata);
  gftpui_show_busy (FALSE);

  g_free (cdata);

  return (1);
}
Exemple #10
0
void
edit_dialog (gpointer data)
{
  gftp_window_data * fromwdata = data;
  char *edit_program;

  gftp_lookup_request_option (fromwdata->request, "edit_program", 
                              &edit_program);

  if (*edit_program == '\0')
    {
      ftp_log (gftp_logging_error, NULL,
	       _("Edit: You must specify an editor in the options dialog\n"));
      return;
    }

  do_view_or_edit_file (data, 0);
}
Exemple #11
0
static void
on_next_transfer (gftp_transfer * tdata)
{
  intptr_t refresh_files;
  gftp_file * tempfle;

  tdata->next_file = 0;
  for (; tdata->updfle != tdata->curfle; tdata->updfle = tdata->updfle->next)
    {
      tempfle = tdata->updfle->data;

      if (tempfle->done_view || tempfle->done_edit)
        {
          if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
            {
              view_file (tempfle->destfile, 0, tempfle->done_view,
                         tempfle->done_rm, 1, 0, tempfle->file, NULL);
            }
        }
      else if (tempfle->done_rm)
	tdata->fromreq->rmfile (tdata->fromreq, tempfle->file);
      
      if (tempfle->transfer_action == GFTP_TRANS_ACTION_SKIP)
        gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tempfle->user_data, 1,
  			         _("Skipped"));
      else
        gtk_ctree_node_set_text (GTK_CTREE (dlwdw), tempfle->user_data, 1,
  			         _("Finished"));
    }

  gftp_lookup_request_option (tdata->fromreq, "refresh_files", &refresh_files);

  if (refresh_files && tdata->curfle && tdata->curfle->next &&
      compare_request (tdata->toreq, 
                       ((gftp_window_data *) tdata->towdata)->request, 1))
    gftpui_refresh (tdata->towdata, 1);
}
Exemple #12
0
void
view_file (char *filename, int fd, unsigned int viewedit, unsigned int del_file,
           unsigned int start_pos, unsigned int dontupload,
           char *remote_filename, gftp_window_data * wdata)
{
  GtkWidget * dialog, * view, * table, * tempwid;
  char buf[8192], *view_program, *edit_program;
  gftp_config_list_vars * tmplistvar;
  gftp_file_extensions * tempext;
  gftp_viewedit_data * newproc;
  GtkAdjustment * vadj;
  GList * templist;
  size_t stlen;
  int doclose;
  ssize_t n;
  char * non_utf8;
  GtkTextBuffer * textbuf;
  GtkTextIter iter;

  doclose = 1;
  stlen = strlen (filename);
  gftp_lookup_global_option ("ext", &tmplistvar);
  for (templist = tmplistvar->list; templist != NULL; templist = templist->next)
    {
      tempext = templist->data;
      if (stlen >= tempext->stlen &&
          strcmp (&filename[stlen - tempext->stlen], tempext->ext) == 0)
        {
          if (*tempext->view_program == '\0')
            break;
          ftp_log (gftp_logging_misc, NULL, _("Opening %s with %s\n"),
                   filename, tempext->view_program);
          fork_process (tempext->view_program, filename, fd, remote_filename,
                        viewedit, del_file, dontupload, wdata);
          return;
        }
    }

  if (wdata != NULL)
    {
      gftp_lookup_request_option (wdata->request, "view_program", &view_program);
      gftp_lookup_request_option (wdata->request, "edit_program", &edit_program);
      if ((non_utf8 = gftp_filename_from_utf8 (wdata->request, filename, NULL)) == NULL) /* freeme later! */
        non_utf8 = filename;
    }
  else
    {
      gftp_lookup_global_option ("view_program", &view_program);
      gftp_lookup_global_option ("edit_program", &edit_program);
      non_utf8 = filename;
    }

  if (viewedit && *view_program != '\0')
    {
      /* Open the file with the default file viewer */
      fork_process (view_program, filename, fd, remote_filename, viewedit,
                    del_file, dontupload, wdata);
      if (non_utf8 != filename && non_utf8)
        g_free (non_utf8);
      return;
    }
  else if (!viewedit && *edit_program != '\0')
    {
      /* Open the file with the default file editor */
      newproc = fork_process (edit_program, filename, fd, remote_filename, 
                              viewedit, del_file, dontupload, wdata);
      stat (non_utf8, &newproc->st);
      if (non_utf8 != filename && non_utf8)
        g_free (non_utf8);
      return;
    }

  ftp_log (gftp_logging_misc, NULL, _("Viewing file %s\n"), filename);

  if (fd == 0)
    {
      if ((fd = open (non_utf8, O_RDONLY)) < 0)
        {
          ftp_log (gftp_logging_error, NULL, 
                   _("View: Cannot open file %s: %s\n"), non_utf8, 
                   g_strerror (errno));
          if (non_utf8 != filename && non_utf8)
            g_free (non_utf8);
          return;
        }
      doclose = 1;
    }
  else
    {
      lseek (fd, 0, SEEK_SET);
      doclose = 0;
    }

  if (del_file)
    {
      if (unlink (non_utf8) == 0)
        ftp_log (gftp_logging_misc, NULL, _("Successfully removed %s\n"), 
                 filename);
      else
        ftp_log (gftp_logging_error, NULL,
                 _("Error: Could not remove file %s: %s\n"), filename, 
                 g_strerror (errno));
    }

  if (non_utf8 != filename && non_utf8)
    g_free (non_utf8);

  dialog = gtk_dialog_new_with_buttons (filename, NULL, 0,
                                        GTK_STOCK_CLOSE,
                                        GTK_RESPONSE_CLOSE,
                                        NULL);

  gtk_window_set_wmclass (GTK_WINDOW(dialog), "fileview", "gFTP");
  gtk_container_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
  gtk_widget_realize (dialog);

  if (gftp_icon != NULL)
    {
      gdk_window_set_icon (dialog->window, NULL, gftp_icon->pixmap,
                           gftp_icon->bitmap);
      gdk_window_set_icon_name (dialog->window, gftp_version);
    }

  table = gtk_table_new (1, 2, FALSE);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);

  view = gtk_text_view_new ();
  gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE);
  gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view), FALSE);
  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);

  tempwid = gtk_scrolled_window_new (NULL, NULL);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tempwid),
                                 GTK_POLICY_AUTOMATIC,
                                 GTK_POLICY_AUTOMATIC);

  gtk_container_add (GTK_CONTAINER (tempwid), view);
  gtk_widget_show (view);

  gtk_table_attach (GTK_TABLE (table), tempwid, 0, 1, 0, 1,
		    GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND | GTK_SHRINK,
		    0, 0);
  gtk_widget_show (tempwid);

  vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (tempwid));
  gtk_widget_set_size_request (table, 500, 400);
  gtk_widget_show (table);

  g_signal_connect_swapped (GTK_OBJECT (dialog), "response",
                            G_CALLBACK (gtk_widget_destroy),
                            GTK_OBJECT (dialog));

  buf[sizeof (buf) - 1] = '\0';
  while ((n = read (fd, buf, sizeof (buf) - 1)) > 0)
    {
      buf[n] = '\0';
      textbuf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
      gtk_text_buffer_get_iter_at_offset (textbuf, &iter, -1);
      gtk_text_buffer_insert (textbuf, &iter, buf, -1);
    }

  if (doclose)
    close (fd);

  gtk_widget_show (dialog);

  if (!start_pos)
    gtk_adjustment_set_value (vadj, vadj->upper);
}
Exemple #13
0
off_t
gftp_transfer_file (gftp_request * fromreq, const char *fromfile, 
                    off_t fromsize, gftp_request * toreq, const char *tofile,
                    off_t tosize)
{
  /* Needed for systems that size(float) < size(void *) */
  union { intptr_t i; float f; } maxkbs;
  off_t size;
  int ret;

  g_return_val_if_fail (fromreq != NULL, GFTP_EFATAL);
  g_return_val_if_fail (fromfile != NULL, GFTP_EFATAL);
  g_return_val_if_fail (toreq != NULL, GFTP_EFATAL);
  g_return_val_if_fail (tofile != NULL, GFTP_EFATAL);

  gftp_lookup_request_option (toreq, "maxkbs", &maxkbs.f);

  if (maxkbs.f > 0)
    {
      toreq->logging_function (gftp_logging_misc, toreq,
                    _("File transfer will be throttled to %.2f KB/s\n"), 
                    maxkbs.f);
    }

  if (fromreq->protonum == toreq->protonum &&
      fromreq->transfer_file != NULL)
    return (fromreq->transfer_file (fromreq, fromfile, fromsize, toreq, 
                                    tofile, tosize));

  fromreq->cached = 0;
  toreq->cached = 0;

get_file:
  size = gftp_get_file (fromreq, fromfile, tosize);
  if (size < 0)
    {
      if (size == GFTP_ETIMEDOUT)
        {
          ret = gftp_connect (fromreq);
          if (ret < 0)
            return (ret);

          goto get_file;
        }

      return (size);
    }

put_file:
  ret = gftp_put_file (toreq, tofile, tosize, size);
  if (ret != 0)
    {
      if (size == GFTP_ETIMEDOUT)
        {
          ret = gftp_connect (fromreq);
          if (ret < 0)
            return (ret);

          goto put_file;
        }

      if (gftp_abort_transfer (fromreq) != 0)
        gftp_end_transfer (fromreq);

      return (ret);
    }

  return (size);
}
Exemple #14
0
int
gftp_parse_bookmark (gftp_request * request, gftp_request * local_request, 
                     const char * bookmark, int *refresh_local)
{
  gftp_logging_func logging_function;
  gftp_bookmarks_var * tempentry;
  char *default_protocol;
  const char *email;
  int i, init_ret;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (bookmark != NULL, GFTP_EFATAL);
  
  logging_function = request->logging_function;
  gftp_request_destroy (request, 0);
  request->logging_function = logging_function;

  if ((tempentry = g_hash_table_lookup (gftp_bookmarks_htable, 
                                        bookmark)) == NULL)
    {
      request->logging_function (gftp_logging_error, request,
                                 _("Error: Could not find bookmark %s\n"), 
                                 bookmark);
      return (GFTP_EFATAL);
    }
  else if (tempentry->hostname == NULL || *tempentry->hostname == '\0')
    {
      request->logging_function (gftp_logging_error, request,
                                 _("Bookmarks Error: The bookmark entry %s does not have a hostname\n"), bookmark);
      return (GFTP_EFATAL);
    }

  if (tempentry->user != NULL)
    gftp_set_username (request, tempentry->user);

  if (tempentry->pass != NULL)
    {
      if (strcmp (tempentry->pass, "@EMAIL@") == 0)
        {
          gftp_lookup_request_option (request, "email", &email);
          gftp_set_password (request, email);
        }
      else
        gftp_set_password (request, tempentry->pass);
    }

  if (tempentry->acct != NULL)
    gftp_set_account (request, tempentry->acct);

  gftp_set_hostname (request, tempentry->hostname);
  gftp_set_directory (request, tempentry->remote_dir);
  gftp_set_port (request, tempentry->port);

  if (local_request != NULL && tempentry->local_dir != NULL &&
      *tempentry->local_dir != '\0')
    {
      gftp_set_directory (local_request, tempentry->local_dir);
      if (refresh_local != NULL)
        *refresh_local = 1;
    }
  else if (refresh_local != NULL)
    *refresh_local = 0;

  for (i = 0; gftp_protocols[i].name; i++)
    {
      if (strcmp (gftp_protocols[i].name, tempentry->protocol) == 0)
        {
          if ((init_ret = gftp_protocols[i].init (request)) < 0)
            {
              gftp_request_destroy (request, 0);
              return (init_ret);
            }
          break;
        }
    }

  if (gftp_protocols[i].name == NULL)
    {
      gftp_lookup_request_option (request, "default_protocol", 
                                  &default_protocol);

      if (default_protocol != NULL && *default_protocol != '\0')
        {
          for (i = 0; gftp_protocols[i].url_prefix; i++)
            {
              if (strcmp (gftp_protocols[i].name, default_protocol) == 0)
                break;
            }
        }

      if (gftp_protocols[i].url_prefix == NULL)
        i = GFTP_FTP_NUM;
    }

  gftp_copy_local_options (&request->local_options_vars,
                           &request->local_options_hash,
                           &request->num_local_options_vars,
                           tempentry->local_options_vars,
                           tempentry->num_local_options_vars);

  if ((init_ret = gftp_protocols[i].init (request)) < 0)
    {
      gftp_request_destroy (request, 0);
      return (init_ret);
    }

  return (0);
}
Exemple #15
0
int
gftp_parse_url (gftp_request * request, const char *url)
{
  char *pos, *endpos, *default_protocol, *new_url;
  gftp_logging_func logging_function;
  const char *clear_pos;
  int i, ret;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (url != NULL, GFTP_EFATAL);

  logging_function = request->logging_function;
  gftp_request_destroy (request, 0);
  request->logging_function = logging_function;

  for (clear_pos = url;
       *clear_pos == ' ' || *clear_pos == '\t';
       clear_pos++);

  new_url = g_strdup (clear_pos);

  for (pos = new_url + strlen (new_url) - 1;
       *pos == ' ' || *pos == '\t';
       pos--)
    *pos = '\0';

  /* See if the URL has a protocol... */
  if ((pos = strstr (new_url, "://")) != NULL)
    {
      *pos = '\0';

      for (i = 0; gftp_protocols[i].url_prefix; i++)
        {
          if (strcmp (gftp_protocols[i].url_prefix, new_url) == 0)
            break;
        }

      if (gftp_protocols[i].url_prefix == NULL)
        {
          request->logging_function (gftp_logging_error, NULL, 
                                     _("The protocol '%s' is currently not supported.\n"),
                                     new_url);
          g_free (new_url);
          return (GFTP_EFATAL);
        }

      *pos = ':';
      pos += 3;
    }
  else
    {
      gftp_lookup_request_option (request, "default_protocol", 
                                  &default_protocol);

      i = GFTP_FTP_NUM;
      if (default_protocol != NULL && *default_protocol != '\0')
        {
          for (i = 0; gftp_protocols[i].url_prefix; i++)
            {
              if (strcmp (gftp_protocols[i].name, default_protocol) == 0)
                break;
            }
        }

      if (gftp_protocols[i].url_prefix == NULL)
        {
          request->logging_function (gftp_logging_error, NULL, 
                                     _("The protocol '%s' is currently not supported.\n"),
                                     default_protocol);
          g_free (new_url);
          return (GFTP_EFATAL);
        }

      pos = new_url;
    }

  if ((ret = gftp_protocols[i].init (request)) < 0)
    {
      gftp_request_destroy (request, 0);
      return (ret);
    }

  if ((endpos = strchr (pos, '/')) != NULL)
    {
      gftp_set_directory (request, endpos);
      *endpos = '\0';
    }

  if (request->parse_url != NULL)
    {
      ret = request->parse_url (request, new_url);
      g_free (new_url);
      return (ret);
    }

  if (*pos != '\0')
    {
      if (endpos == NULL)
        endpos = pos + strlen (pos) - 1;
      else
        endpos--;

      for (; isdigit (*endpos); endpos--);

      if (*endpos == ':' && isdigit (*(endpos + 1)))
        {
          gftp_set_port (request, strtol (endpos + 1, NULL, 10));
          *endpos = '\0';
        }

      if ((endpos = strrchr (pos, '@')) != NULL)
        {
          gftp_set_hostname (request, endpos + 1);
          *endpos = '\0';

          if ((endpos = strchr (pos, ':')) != NULL)
            {
              *endpos = '\0';
              gftp_set_username (request, pos);
              gftp_set_password (request, endpos + 1);
            }
          else
            {
              gftp_set_username (request, pos);
              gftp_set_password (request, "");
            }
        }
      else
        gftp_set_hostname (request, pos);
    }

  g_free (new_url);
  return (0);
}
Exemple #16
0
ssize_t 
gftp_fd_write (gftp_request * request, const char *ptr, size_t size, int fd)
{
  intptr_t network_timeout;
  struct timeval tv;
  int ret, s_ret;
  ssize_t w_ret;
  fd_set fset;

  g_return_val_if_fail (fd >= 0, GFTP_EFATAL);

  gftp_lookup_request_option (request, "network_timeout", &network_timeout);  

  errno = 0;
  ret = 0;
  FD_ZERO (&fset);

  do
    {
      FD_SET (fd, &fset);
      tv.tv_sec = network_timeout;
      tv.tv_usec = 0;
      s_ret = select (fd + 1, NULL, &fset, NULL, &tv);
      if (s_ret == -1 && (errno == EINTR || errno == EAGAIN))
        {
          if (request != NULL && request->cancel)
            {
              gftp_disconnect (request);
              return (GFTP_ERETRYABLE);
            }

          continue;
        }
      else if (s_ret <= 0)
        {
          if (request != NULL)
            {
              request->logging_function (gftp_logging_error, request,
                                         _("Connection to %s timed out\n"),
                                         request->hostname);
              gftp_disconnect (request);
            }

          return (GFTP_ERETRYABLE);
        }

      w_ret = write (fd, ptr, size);
      if (w_ret < 0)
        {
          if (errno == EINTR || errno == EAGAIN)
            {
              if (request != NULL && request->cancel)
                {
                  gftp_disconnect (request);
                  return (GFTP_ERETRYABLE);
                }

              continue;
             }
 
          if (request != NULL)
            {
              request->logging_function (gftp_logging_error, request,
                                    _("Error: Could not write to socket: %s\n"),
                                    g_strerror (errno));
              gftp_disconnect (request);
            }

          return (GFTP_ERETRYABLE);
        }

      ptr += w_ret;
      size -= w_ret;
      ret += w_ret;
    }
  while (size > 0);

  return (ret);
}
Exemple #17
0
gftp_transfer *
gftpui_common_add_file_transfer (gftp_request * fromreq, gftp_request * toreq,
                                 void *fromuidata, void *touidata,
                                 GList * files)
{
  intptr_t append_transfers, one_transfer, overwrite_default;
  GList * templist, *curfle;
  gftp_transfer * tdata;
  gftp_file * tempfle;
  int show_dialog;
  
  gftp_lookup_request_option (fromreq, "overwrite_default", &overwrite_default);
  gftp_lookup_request_option (fromreq, "append_transfers", &append_transfers);
  gftp_lookup_request_option (fromreq, "one_transfer", &one_transfer);

  if (!overwrite_default)
    {
      for (templist = files; templist != NULL; templist = templist->next)
        { 
          tempfle = templist->data;
          if (tempfle->startsize > 0 && !S_ISDIR (tempfle->st_mode))
            break;
        }

      show_dialog = templist != NULL;
    }
  else
    show_dialog = 0;

  tdata = NULL;
  if (append_transfers && one_transfer && !show_dialog)
    {
      if (g_thread_supported ())
        g_static_mutex_lock (&gftpui_common_transfer_mutex);

      for (templist = gftp_file_transfers;
           templist != NULL;
           templist = templist->next)
        {
          tdata = templist->data;

          if (g_thread_supported ())
            g_static_mutex_lock (&tdata->structmutex);

          if (!compare_request (tdata->fromreq, fromreq, 0) ||
              !compare_request (tdata->toreq, toreq, 0) ||
              tdata->curfle == NULL)
            {
              if (g_thread_supported ())
                g_static_mutex_unlock (&tdata->structmutex);

              continue;
            }

          tdata->files = g_list_concat (tdata->files, files);

          for (curfle = files; curfle != NULL; curfle = curfle->next)
            {
              tempfle = curfle->data;

              if (S_ISDIR (tempfle->st_mode))
                tdata->numdirs++;
              else
                tdata->numfiles++;

              if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
                tdata->total_bytes += tempfle->size;

              gftpui_add_file_to_transfer (tdata, curfle);
            }

          if (g_thread_supported ())
            g_static_mutex_unlock (&tdata->structmutex);

          break;
        }

      if (g_thread_supported ())
        g_static_mutex_unlock (&gftpui_common_transfer_mutex);
    }
  else
    templist = NULL;

  if (templist == NULL)
    {
      tdata = gftp_tdata_new ();
      tdata->fromreq = gftp_copy_request (fromreq);
      tdata->toreq = gftp_copy_request (toreq);

      tdata->fromwdata = fromuidata;
      tdata->towdata = touidata;

      if (!show_dialog)
        tdata->show = tdata->ready = 1;

      tdata->files = files;
      for (curfle = files; curfle != NULL; curfle = curfle->next)
        {
          tempfle = curfle->data;
          if (S_ISDIR (tempfle->st_mode))
            tdata->numdirs++;
          else
            tdata->numfiles++;

          if (tempfle->transfer_action != GFTP_TRANS_ACTION_SKIP)
            tdata->total_bytes += tempfle->size;
        }

      if (g_thread_supported ())
        g_static_mutex_lock (&gftpui_common_transfer_mutex);

      gftp_file_transfers = g_list_append (gftp_file_transfers, tdata);

      if (g_thread_supported ())
        g_static_mutex_unlock (&gftpui_common_transfer_mutex);

      if (show_dialog)
        gftpui_ask_transfer (tdata);
    }

  gftpui_start_transfer (tdata);
  return (tdata);
}
Exemple #18
0
int
gftp_get_transfer_status (gftp_transfer * tdata, ssize_t num_read)
{
  intptr_t retries, sleep_time;
  gftp_file * tempfle;
  int ret1, ret2;

  gftp_lookup_request_option (tdata->fromreq, "retries", &retries);
  gftp_lookup_request_option (tdata->fromreq, "sleep_time", &sleep_time);

  if (g_thread_supported ())
    g_static_mutex_lock (&tdata->structmutex);

  if (tdata->curfle == NULL)
    {
      if (g_thread_supported ())
        g_static_mutex_unlock (&tdata->structmutex);

      return (GFTP_EFATAL);
    }

  tempfle = tdata->curfle->data;

  if (g_thread_supported ())
    g_static_mutex_unlock (&tdata->structmutex);

  gftp_disconnect (tdata->fromreq);
  gftp_disconnect (tdata->toreq);

  if (tdata->cancel || num_read == GFTP_EFATAL)
    return (GFTP_EFATAL);
  else if (num_read >= 0 && !tdata->skip_file)
    return (0);

  if (num_read != GFTP_ETIMEDOUT && !tdata->conn_error_no_timeout)
    {
      if (retries != 0 && 
          tdata->current_file_retries >= retries)
        {
          tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
                   _("Error: Remote site %s disconnected. Max retries reached...giving up\n"),
                   tdata->fromreq->hostname != NULL ? 
                         tdata->fromreq->hostname : tdata->toreq->hostname);
          return (GFTP_EFATAL);
        }
      else
        {
          tdata->fromreq->logging_function (gftp_logging_error, tdata->fromreq,
                     _("Error: Remote site %s disconnected. Will reconnect in %d seconds\n"),
                     tdata->fromreq->hostname != NULL ? 
                         tdata->fromreq->hostname : tdata->toreq->hostname, 
                     sleep_time);
        }
    }

  while (retries == 0 || 
         tdata->current_file_retries <= retries)
    {
      /* Look up the options in case the user changes them... */
      gftp_lookup_request_option (tdata->fromreq, "retries", &retries);
      gftp_lookup_request_option (tdata->fromreq, "sleep_time", &sleep_time);

      if (num_read != GFTP_ETIMEDOUT && !tdata->conn_error_no_timeout &&
          !tdata->skip_file)
        _do_sleep (sleep_time);

      tdata->current_file_retries++;

      ret1 = ret2 = 0;
      if ((ret1 = gftp_connect (tdata->fromreq)) == 0 &&
          (ret2 = gftp_connect (tdata->toreq)) == 0)
        {
          if (g_thread_supported ())
            g_static_mutex_lock (&tdata->structmutex);

          tdata->resumed_bytes = tdata->resumed_bytes + tdata->trans_bytes - tdata->curresumed - tdata->curtrans;
          tdata->trans_bytes = 0;
          if (tdata->skip_file)
            {
              tdata->total_bytes -= tempfle->size;
              tdata->curtrans = 0;

              tdata->curfle = tdata->curfle->next;
              tdata->next_file = 1;
              tdata->skip_file = 0;
              tdata->cancel = 0;
              tdata->fromreq->cancel = 0;
              tdata->toreq->cancel = 0;
            }
          else
            {
              tempfle->transfer_action = GFTP_TRANS_ACTION_RESUME;
              tempfle->startsize = tdata->curtrans + tdata->curresumed;
              /* We decrement this here because it will be incremented in 
                 the loop again */
              tdata->curresumed = 0;
              tdata->current_file_number--; /* Decrement this because it 
                                               will be incremented when we 
                                               continue in the loop */
            }

          gettimeofday (&tdata->starttime, NULL);

          if (g_thread_supported ())
            g_static_mutex_unlock (&tdata->structmutex);

          return (GFTP_ERETRYABLE);
        }
      else if (ret1 == GFTP_EFATAL || ret2 == GFTP_EFATAL)
        {
          gftp_disconnect (tdata->fromreq);
          gftp_disconnect (tdata->toreq);
          return (GFTP_EFATAL);
        }
    }

  return (0);
}