Exemple #1
0
gboolean
g_vfs_ftp_task_login (GVfsFtpTask *task,
                      const char * username,
                      const char * password)
{
  guint status;

  g_return_val_if_fail (task != NULL, FALSE);
  g_return_val_if_fail (username != NULL, FALSE);
  g_return_val_if_fail (password != NULL, FALSE);

  if (g_vfs_ftp_task_is_in_error (task))
    return FALSE;

  status = g_vfs_ftp_task_send (task, G_VFS_FTP_PASS_300,
                                "USER %s", username);
 
  if (G_VFS_FTP_RESPONSE_GROUP (status) == 3)
    {
      /* rationale for choosing the default password:
       * - some ftp servers expect something that looks like an email address
       * - we don't want to send the user's name or address, as that would be
       *   a privacy problem
       * - we want to give ftp server administrators a chance to notify us of
       *   problems with our client.
       * - we don't want to drown in spam.
       */
      if (password == NULL || password[0] == 0)
        password = "******" VERSION "@example.com";
      status = g_vfs_ftp_task_send (task, 0,
        			    "PASS %s", password);
    }

  return status;
}
Exemple #2
0
/**
 * g_vfs_ftp_task_setup_connection:
 * @task: the task
 *
 * Sends all commands necessary to put the connection into a usable state,
 * like setting the transfer mode to binary. Note that passive mode will
 * will be set on a case-by-case basis when opening a data connection.
 **/
void
g_vfs_ftp_task_setup_connection (GVfsFtpTask *task)
{
  g_return_if_fail (task != NULL);

  /* only binary transfers please */
  g_vfs_ftp_task_send (task, 0, "TYPE I");
  if (g_vfs_ftp_task_is_in_error (task))
    return;

#if 0
  /* RFC 2428 suggests to send this to make NAT routers happy */
  /* XXX: Disabled for the following reasons:
   * - most ftp clients don't use it
   * - lots of broken ftp servers can't see the difference between
   *   "EPSV" and "EPSV ALL"
   * - impossible to dynamically fall back to regular PASV in case
   *   EPSV doesn't work for some reason.
   * If this makes your ftp connection fail, please file a bug and we will
   * try to invent a way to make this all work. Until then, we'll just
   * ignore the RFC.
   */
  if (g_vfs_backend_ftp_has_feature (task->backend, g_VFS_FTP_FEATURE_EPSV))
    g_vfs_ftp_task_send (task, 0, "EPSV ALL");
  g_vfs_ftp_task_clear_error (task);
#endif

  /* instruct server that we'll give and assume we get utf8 */
  if (g_vfs_backend_ftp_has_feature (task->backend, G_VFS_FTP_FEATURE_UTF8))
    {
      if (!g_vfs_ftp_task_send (task, 0, "OPTS UTF8 ON"))
        g_vfs_ftp_task_clear_error (task);
    }
}
Exemple #3
0
static GVfsFtpDirCacheEntry *
g_vfs_ftp_dir_cache_lookup_entry (GVfsFtpDirCache *  cache,
                                  GVfsFtpTask *      task,
                                  const GVfsFtpFile *dir,
                                  guint              stamp)
{
  GVfsFtpDirCacheEntry *entry;

  g_mutex_lock (cache->lock);
  entry = g_hash_table_lookup (cache->directories, dir);
  if (entry)
    g_vfs_ftp_dir_cache_entry_ref (entry);
  g_mutex_unlock (cache->lock);
  if (entry && entry->stamp < stamp)
    g_vfs_ftp_dir_cache_entry_unref (entry);
  else if (entry)
    return entry;

  if (g_vfs_ftp_task_send (task,
        	           G_VFS_FTP_PASS_550,
        		   "CWD %s", g_vfs_ftp_file_get_ftp_path (dir)) == 550)
    {
      g_set_error_literal (&task->error,
        	           G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
        		   _("The file is not a directory"));
    }
  g_vfs_ftp_task_setup_data_connection (task);
  g_vfs_ftp_task_send (task,
        	       G_VFS_FTP_PASS_100 | G_VFS_FTP_FAIL_200,
                       "%s", cache->funcs->command);
  g_vfs_ftp_task_open_data_connection (task);
  if (g_vfs_ftp_task_is_in_error (task))
    return NULL;

  entry = g_vfs_ftp_dir_cache_entry_new (stamp);
  cache->funcs->process (g_io_stream_get_input_stream (g_vfs_ftp_connection_get_data_stream (task->conn)),
                         g_vfs_ftp_connection_get_debug_id (task->conn),
                         dir,
                         entry,
                         task->cancellable,
                         &task->error);
  g_vfs_ftp_task_close_data_connection (task);
  g_vfs_ftp_task_receive (task, 0, NULL);
  if (g_vfs_ftp_task_is_in_error (task))
    {
      g_vfs_ftp_dir_cache_entry_unref (entry);
      return NULL;
    }
  g_mutex_lock (cache->lock);
  g_hash_table_insert (cache->directories,
                       g_vfs_ftp_file_copy (dir),
                       g_vfs_ftp_dir_cache_entry_ref (entry));
  g_mutex_unlock (cache->lock);
  return entry;
}
Exemple #4
0
static GFileInfo *
g_vfs_ftp_dir_cache_funcs_lookup_uncached (GVfsFtpTask *      task,
                                           const GVfsFtpFile *file)
{
  GFileInfo *info;
  char **reply;

  if (g_vfs_ftp_file_is_root (file))
    return create_root_file_info (task->backend);

  /* the directory cache fails when the parent directory of the file is not readable.
   * This cannot happen on Unix, but it can happen on FTP.
   * In this case we try to figure out as much as possible about the file (does it even exist?)
   * using standard ftp commands.
   */
  if (g_vfs_ftp_task_send (task, 0, "CWD %s", g_vfs_ftp_file_get_ftp_path (file)))
    {
      char *tmp;

      info = g_file_info_new ();

      tmp = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, tmp);
      g_free (tmp);

      gvfs_file_info_populate_default (info, g_vfs_ftp_file_get_gvfs_path (file), G_FILE_TYPE_DIRECTORY);

      g_file_info_set_is_hidden (info, TRUE);
      
      return info;
    }
  
  g_vfs_ftp_task_clear_error (task);
  if (g_vfs_ftp_task_send_and_check (task, 0, NULL, NULL, &reply, "SIZE %s", g_vfs_ftp_file_get_ftp_path (file)))
    {
      char *tmp;

      info = g_file_info_new ();

      tmp = g_path_get_basename (g_vfs_ftp_file_get_gvfs_path (file));
      g_file_info_set_name (info, tmp);
      g_free (tmp);

      gvfs_file_info_populate_default (info, g_vfs_ftp_file_get_gvfs_path (file), G_FILE_TYPE_REGULAR);

      g_file_info_set_size (info, g_ascii_strtoull (reply[0] + 4, NULL, 0));
      g_strfreev (reply);

      g_file_info_set_is_hidden (info, TRUE);
      return info;
    }
      
  g_vfs_ftp_task_clear_error (task);

  /* note that there might still be a file/directory, we just have
   * no way to figure this out (in particular on ftp servers that
   * don't support SIZE.
   * If you have ways to improve file detection, patches are welcome. */

  return NULL;
}