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; }
/** * 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); } }
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; }
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; }