another patch for ftp and ssh modules
- From: Christophe Fergeau <teuf users sourceforge net>
- To: gnome-vfs-list gnome org
- Subject: another patch for ftp and ssh modules
- Date: Wed, 4 Sep 2002 10:15:19 +0200
Hi,
Here is a patch which cumulates all the patches I sent to this list (apart from the one for the libgnomevfs dir).
I also made more changes to the ssh module. Now it can properly report when it couldn't connect because a password was needed (btw, if someone wants to review the code which does that, it is the first time I use select, so I probably made some dumb things).
It would also be nice if the user could specify a password which would then be used to connect if needed, but I did not manage to do it (I don't know how to get a fd where I can send the password so that ssh receives it as input). If someone is interested in getting that to work, the kde fish ioslave seems to do that (but I did not understand the code at all, so I can't do it myself :)
The patch for the ssh method also correctly escapes the quotes contained in file names.
Christophe
? gnomevfs.diff
? modules.diff
Index: ftp-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/ftp-method.c,v
retrieving revision 1.87
diff -u -r1.87 ftp-method.c
--- ftp-method.c 8 May 2002 19:04:51 -0000 1.87
+++ ftp-method.c 4 Sep 2002 07:59:58 -0000
@@ -42,15 +42,18 @@
#include <netinet/in.h>
#include <arpa/inet.h>
+
#include <libgnomevfs/gnome-vfs-context.h>
#include <libgnomevfs/gnome-vfs-inet-connection.h>
#include <libgnomevfs/gnome-vfs-iobuf.h>
#include <libgnomevfs/gnome-vfs-method.h>
#include <libgnomevfs/gnome-vfs-mime.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
-#include <libgnomevfs/gnome-vfs-module-shared.h>
#include <libgnomevfs/gnome-vfs-module.h>
+#include <libgnomevfs/gnome-vfs-module-callback-module-api.h>
+#include <libgnomevfs/gnome-vfs-module-shared.h>
#include <libgnomevfs/gnome-vfs-parse-ls.h>
+#include <libgnomevfs/gnome-vfs-standard-callbacks.h>
#include <libgnomevfs/gnome-vfs-utils.h>
#include <stdio.h> /* for sscanf */
#include <stdlib.h> /* for atoi */
@@ -504,12 +507,62 @@
}
+
+static GnomeVFSResult ftp_login(FtpConnection *conn,
+ const char *user, const char *password)
+{
+ gchar *tmpstring;
+ GnomeVFSResult result;
+ static gboolean first_login_attempt = TRUE;
+
+ tmpstring = g_strdup_printf ("USER %s", user);
+ result = do_basic_command (conn, tmpstring);
+ g_free (tmpstring);
+
+ if (IS_300 (conn->response_code)) {
+ tmpstring = g_strdup_printf ("PASS %s", password);
+ result = do_basic_command (conn, tmpstring);
+ g_free (tmpstring);
+ }
+
+ gnome_vfs_uri_set_user_name(conn->uri, user);
+ gnome_vfs_uri_set_password(conn->uri, password);
+
+ if ((result != GNOME_VFS_OK) && (first_login_attempt)) {
+ GnomeVFSModuleCallbackAuthenticationIn in;
+ GnomeVFSModuleCallbackAuthenticationOut out;
+ gboolean callback_called;
+
+ in.uri = gnome_vfs_uri_to_string(conn->uri, FALSE);
+ in.realm = NULL;
+ in.previous_attempt_failed = FALSE;
+ in.auth_type = AuthTypeBasic;
+
+ callback_called = gnome_vfs_module_callback_invoke(GNOME_VFS_MODULE_CALLBACK_AUTHENTICATION,
+ &in,
+ sizeof(GnomeVFSModuleCallbackAuthenticationIn),
+ &out,
+ sizeof(GnomeVFSModuleCallbackAuthenticationOut));
+ if (callback_called) {
+ first_login_attempt = FALSE;
+ result = ftp_login(conn, out.username, out.password);
+ gnome_vfs_uri_set_user_name(conn->uri, out.username);
+ gnome_vfs_uri_set_password(conn->uri, out.password);
+ g_free(out.username);
+ g_free(out.password);
+ }
+ }
+
+ first_login_attempt = TRUE;
+ return result;
+}
+
+
static GnomeVFSResult
ftp_connection_create (FtpConnection **connptr, GnomeVFSURI *uri, GnomeVFSContext *context)
{
FtpConnection *conn = g_new0 (FtpConnection, 1);
GnomeVFSResult result;
- gchar *tmpstring;
gint port = control_port;
const gchar *user = anon_user;
const gchar *pass = anon_pass;
@@ -573,16 +626,8 @@
return result;
}
- tmpstring = g_strdup_printf ("USER %s", user);
- result = do_basic_command (conn, tmpstring);
- g_free (tmpstring);
-
- if (IS_300 (conn->response_code)) {
- tmpstring = g_strdup_printf ("PASS %s", pass);
- result = do_basic_command (conn, tmpstring);
- g_free (tmpstring);
- }
-
+ result = ftp_login(conn, user, pass);
+
if (result != GNOME_VFS_OK) {
/* login failed */
g_warning ("FTP server said: \"%d %s\"\n", conn->response_code,
@@ -592,6 +637,7 @@
gnome_vfs_uri_unref (conn->uri);
g_string_free (conn->response_buffer, TRUE);
g_free (conn);
+
return result;
}
@@ -785,7 +831,7 @@
gboolean
do_is_local (GnomeVFSMethod *method,
const GnomeVFSURI *uri)
-{
+{
return FALSE;
}
@@ -860,7 +906,7 @@
GnomeVFSContext *context)
{
FtpConnection *conn = (FtpConnection * )method_handle;
-
+ GnomeVFSResult result;
#if 0
/*
if (conn->operation != FTP_READ) {
@@ -870,7 +916,11 @@
g_print ("do_read (%p)\n", method_handle);
#endif
- return gnome_vfs_iobuf_read (conn->data_iobuf, buffer, num_bytes, bytes_read);
+ result = gnome_vfs_iobuf_read (conn->data_iobuf, buffer, num_bytes, bytes_read);
+ if (*bytes_read == 0) {
+ result = GNOME_VFS_ERROR_EOF;
+ }
+ return result;
}
static GnomeVFSResult
Index: ssh-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/ssh-method.c,v
retrieving revision 1.8.2.1
diff -u -r1.8.2.1 ssh-method.c
--- ssh-method.c 19 Jul 2002 07:57:11 -0000 1.8.2.1
+++ ssh-method.c 4 Sep 2002 08:00:08 -0000
@@ -21,7 +21,6 @@
Author: Ian McKellar <yakk yakk net> */
#include <config.h>
-
#include <errno.h>
#include <glib/gstrfuncs.h>
#include <libgnomevfs/gnome-vfs-cancellation.h>
@@ -37,6 +36,15 @@
#include <unistd.h>
#include <signal.h>
+#define LINE_LENGTH 4096 /* max line length we'll grok */
+
+//#define DEBUG_SSH
+#ifdef DEBUG_SSH
+#define DEBUG(msg) g_print("%s: %s\n", G_GNUC_PRETTY_FUNCTION, (msg))
+#else
+#define DEBUG(msg)
+#endif
+
typedef struct {
GnomeVFSMethodHandle method_handle;
GnomeVFSURI *uri;
@@ -47,6 +55,7 @@
GnomeVFSOpenMode open_mode;
int read_fd;
int write_fd;
+ int error_fd;
pid_t pid;
} SshHandle;
@@ -145,6 +154,86 @@
NULL /* create_symbolic_link */
};
+
+static GnomeVFSResult
+ssh_write (SshHandle *handle,
+ gconstpointer buffer,
+ GnomeVFSFileSize num_bytes,
+ GnomeVFSFileSize *bytes_written);
+
+
+static gboolean
+ssh_data_available_on_stderr (SshHandle *handle)
+{
+ struct timeval timeout;
+ fd_set set;
+ int max;
+
+ /* This function checks if there was data output by ssh
+ * on stderr to detect if we could successfully connect
+ * (without that, trying to read from stderr may block)
+ * It first check both stderr and stdout because if we
+ * have data on stdout, we assume there will be nothing
+ * output on stderr (we don't want to block on the first
+ * select for too long if there will be nothing output on
+ * stderr)
+ * FIXME: that's some quite ugly code only to detect if
+ * a try to read from stderr will block. Maybe there is
+ * a cleaner way to do that
+ */
+ FD_ZERO(&set);
+ FD_SET(handle->read_fd, &set);
+ FD_SET(handle->error_fd, &set);
+ timeout.tv_sec = 3;
+ timeout.tv_usec = 0;
+ if (handle->error_fd >= handle->read_fd) {
+ max = handle->error_fd;
+ } else {
+ max = handle->read_fd;
+ }
+ if (select(max+1,&set, NULL, NULL, &timeout) <= 0){
+ return FALSE;
+ }
+ FD_CLR(handle->read_fd, &set);
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ if (select(handle->error_fd+1, &set, NULL, NULL, &timeout) <= 0) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static GnomeVFSResult
+ssh_check_connection (SshHandle *handle)
+{
+ GIOChannel *channel;
+ GIOStatus result;
+ gchar *line;
+
+ if (!ssh_data_available_on_stderr(handle)) {
+ return GNOME_VFS_OK;
+ }
+
+ channel = g_io_channel_unix_new(handle->error_fd);
+ result = g_io_channel_read_line(channel, &line, NULL, NULL, NULL);
+ if (result != G_IO_STATUS_NORMAL) {
+ return GNOME_VFS_OK;
+ }
+ g_io_channel_shutdown(channel, FALSE, NULL);
+ g_io_channel_unref(channel);
+
+ if (strcmp("Permission denied.\r\n", line) == 0) {
+ g_free(line);
+ return GNOME_VFS_ERROR_ACCESS_DENIED;
+ }
+
+ /* FIXME: which other errors can ssh return ? */
+ g_print("Unknown error: %s\n", line);
+ g_free(line);
+ return GNOME_VFS_ERROR_GENERIC;
+}
+
+
/* FIXME: does this like FDs? */
static GnomeVFSResult
ssh_connect (SshHandle **handle_return,
@@ -153,17 +242,22 @@
char ** argv;
SshHandle *handle;
char *command_line;
+ const gchar *username;
int argc;
GError *gerror = NULL;
+ GnomeVFSResult result;
-
- command_line = g_strconcat ("ssh -oBatchmode=yes -x -l ",
- gnome_vfs_uri_get_user_name (uri),
+ username = gnome_vfs_uri_get_user_name(uri);
+ if (username == NULL) {
+ username = g_get_user_name();
+ }
+
+ command_line = g_strconcat ("ssh -oBatchMode=yes -x -l ",
+ username,
" ", gnome_vfs_uri_get_host_name (uri),
- " ", command,
+ " ", "\"LC_ALL=C;", command,"\"",
NULL);
-
g_shell_parse_argv (command_line, &argc, &argv, &gerror);
g_free (command_line);
if (gerror) {
@@ -177,29 +271,39 @@
handle->uri = uri;
g_spawn_async_with_pipes (NULL, argv, NULL,
- G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
- NULL, NULL,
- &handle->pid, &handle->write_fd, &handle->read_fd,
- NULL, &gerror);
+ G_SPAWN_SEARCH_PATH, NULL, NULL,
+ &handle->pid,
+ &handle->write_fd, &handle->read_fd,
+ &handle->error_fd, &gerror);
g_strfreev (argv);
if (gerror) {
g_warning (gerror->message);
g_free (handle);
+ handle = NULL;
+ return GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE;
}
gnome_vfs_uri_ref (handle->uri);
*handle_return = handle;
- return GNOME_VFS_OK;
+ result = ssh_check_connection(handle);
+ if (result != GNOME_VFS_OK) {
+ gnome_vfs_uri_unref (handle->uri);
+ g_free (handle);
+ handle = NULL;
+ }
+ return result;
}
+
static GnomeVFSResult
ssh_destroy (SshHandle *handle)
{
close (handle->read_fd);
close (handle->write_fd);
+ close (handle->error_fd);
gnome_vfs_uri_unref (handle->uri);
kill (handle->pid, SIGINT);
g_free (handle);
@@ -256,26 +360,6 @@
}
#if 0
-static char *ssh_escape (const char *string)
-{
- char *new_str;
- int i,j;
-
- new_str = g_malloc0 (strlen (string)*2+3);
-
- new_str[0]='\'';
-
- for (i=0,j=1; string[i] != '\0'; i++, j++) {
- if (string[i] == '\'') {
- new_str[j] = '\\';
- j++;
- }
- new_str[j] = string[i];
- }
-
- return new_str;
-}
-
static GnomeVFSResult
ssh_send (SshHandle *handle,
const char *string)
@@ -305,27 +389,24 @@
GnomeVFSResult result = GNOME_VFS_OK;
char *cmd;
SshHandle *handle = NULL;
- char *name;
-
- /* FIXME: escape for shell */
- name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ DEBUG("begin");
if (mode == GNOME_VFS_OPEN_READ) {
- /* FIXME: escape for shell */
- cmd = g_strdup_printf ("cat '%s'", name);
+ char *name;
+ char *quoted_name;
+ name = gnome_vfs_unescape_string (uri->text,
+ G_DIR_SEPARATOR_S);
+ quoted_name = g_shell_quote(name);
+ g_free(name);
+
+ cmd = g_strdup_printf ("cat %s", quoted_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
-
+ g_free (quoted_name);
if (result != GNOME_VFS_OK) {
- g_free (name);
return result;
- }
-
- } else if (mode == GNOME_VFS_OPEN_WRITE) {
- g_free (name);
- return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
+ }
} else {
- g_free (name);
return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
}
@@ -333,9 +414,7 @@
handle->type = SSH_FILE;
*method_handle = (GnomeVFSMethodHandle *)handle;
- g_free (name);
-
- return result;
+ return GNOME_VFS_OK;
}
static GnomeVFSResult
@@ -351,33 +430,31 @@
char *cmd;
GnomeVFSResult result;
char *name;
+ char *quoted_name;
- /* FIXME: escape for shell */
- name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
-
+ DEBUG("begin");
if (mode != GNOME_VFS_OPEN_WRITE) {
- g_free (name);
return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
}
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ quoted_name = g_shell_quote(name);
- /* FIXME: escape for shell */
- cmd = g_strdup_printf ("cat > '%s'", name);
+ cmd = g_strdup_printf ("cat > %s", quoted_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
+ g_free (name);
+ g_free (quoted_name);
if (result != GNOME_VFS_OK) {
- g_free (name);
return result;
}
/* FIXME: set perm */
-
handle->open_mode = mode;
handle->type = SSH_FILE;
*method_handle = (GnomeVFSMethodHandle *)handle;
- g_free (name);
return result;
}
@@ -386,6 +463,7 @@
GnomeVFSMethodHandle *method_handle,
GnomeVFSContext *context)
{
+ DEBUG("begin");
return ssh_destroy ((SshHandle *)method_handle);
}
@@ -397,8 +475,15 @@
GnomeVFSFileSize *bytes_read,
GnomeVFSContext *context)
{
- return ssh_read ((SshHandle *)method_handle, buffer, num_bytes,
- bytes_read);
+ GnomeVFSResult result;
+
+ DEBUG("begin");
+ result = ssh_read ((SshHandle *)method_handle, buffer, num_bytes,
+ bytes_read);
+ if (*bytes_read == 0) {
+ result = GNOME_VFS_ERROR_EOF;
+ }
+ return result;
}
/* alternative impl:
@@ -412,6 +497,7 @@
GnomeVFSFileSize *bytes_written,
GnomeVFSContext *context)
{
+ DEBUG("begin");
return ssh_write ((SshHandle *)method_handle, buffer, num_bytes,
bytes_written);
}
@@ -427,29 +513,32 @@
char *cmd = NULL;
GnomeVFSResult result;
char *name;
+ char *quoted_name;
- /* FIXME: escape for shell */
+ DEBUG("begin");
name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ quoted_name = g_shell_quote(name);
- if (strlen (name) > 0) {
- cmd = g_strdup_printf ("ls -l '%s'", name);
+ if (*name != '\0') {
+ cmd = g_strdup_printf ("ls -l %s", quoted_name);
} else {
cmd = g_strdup_printf ("ls -l '/'");
}
-
+
result = ssh_connect (&handle, uri, cmd);
+ g_free (quoted_name);
g_free (name);
g_free (cmd);
if (result != GNOME_VFS_OK) {
+ DEBUG("end");
return result;
}
handle->open_mode = GNOME_VFS_OPEN_NONE;
handle->type = SSH_LIST;
*method_handle = (GnomeVFSMethodHandle *)handle;
-
- return result;
+ DEBUG("end");
return GNOME_VFS_OK;
}
@@ -458,11 +547,10 @@
GnomeVFSMethodHandle *method_handle,
GnomeVFSContext *context)
{
+ DEBUG("begin");
return ssh_destroy ((SshHandle *)method_handle);
}
-#define LINE_LENGTH 4096 /* max line length we'll grok */
-
static GnomeVFSResult
do_read_directory (GnomeVFSMethod *method,
GnomeVFSMethodHandle *method_handle,
@@ -470,23 +558,25 @@
GnomeVFSContext *context)
{
GnomeVFSResult result = GNOME_VFS_OK;
- char line[LINE_LENGTH];
+ char line[LINE_LENGTH+1];
char c;
int i=0;
- GnomeVFSFileSize j;
+ GnomeVFSFileSize bytes_read;
struct stat st;
char *tempfilename, *filename, *linkname;
+ DEBUG("begin");
for (;;) {
tempfilename = NULL;
filename = NULL;
linkname = NULL;
i = 0;
- j = 0;
+ bytes_read = 0;
while (i<LINE_LENGTH) {
- result = ssh_read ((SshHandle *)method_handle, &c, 1, &j);
- if (j == 0 || c == '\r' || c == '\n') {
+ result = ssh_read ((SshHandle *)method_handle, &c,
+ sizeof(char), &bytes_read);
+ if (bytes_read == 0 || c == '\r' || c == '\n') {
break;
}
@@ -497,12 +587,13 @@
line[i] = c;
i++;
}
-
+ /* Here we can have i == LINE_LENGTH which explains
+ * why the size of line is LINE_LENGTH+1
+ */
line[i] = 0;
if (i == 0) {
return GNOME_VFS_ERROR_EOF;
}
-
if (!gnome_vfs_parse_ls_lga (line, &st, &tempfilename, &linkname)) {
/* Maybe the file doesn't exist? */
if (strstr (line, "No such file or directory"))
@@ -556,12 +647,14 @@
char *cmd = NULL;
GnomeVFSResult result;
char *name;
+ char *quoted_name;
- /* FIXME: escape for shell */
+ DEBUG("begin");
name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ quoted_name = g_shell_quote (name);
- if (strlen (name) > 0) {
- cmd = g_strdup_printf ("ls -ld '%s' 2>&1", name);
+ if (*name != '\0') {
+ cmd = g_strdup_printf ("ls -ld %s 2>&1", quoted_name);
} else {
cmd = g_strdup_printf ("ls -ld '/' 2>&1");
}
@@ -569,8 +662,10 @@
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
g_free (name);
+ g_free (quoted_name);
if (result != GNOME_VFS_OK) {
+ DEBUG("end");
return result;
}
@@ -581,7 +676,7 @@
file_info, context);
ssh_destroy (handle);
-
+ DEBUG("end");
return (result == GNOME_VFS_ERROR_EOF ? GNOME_VFS_OK : result);
}
@@ -595,12 +690,13 @@
char *cmd = NULL;
GnomeVFSResult result;
char *name;
+ char *quoted_name;
- /* FIXME: escape for shell */
+ DEBUG("begin");
name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ quoted_name = g_shell_quote (name);
- /* FIXME: escape for shell */
- cmd = g_strdup_printf ("mkdir '%s'", name);
+ cmd = g_strdup_printf ("mkdir %s", quoted_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
g_free (name);
@@ -623,16 +719,19 @@
char *cmd = NULL;
GnomeVFSResult result;
gchar *name;
+ gchar *quoted_name;
+ DEBUG("begin");
name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
if (name == NULL)
return GNOME_VFS_ERROR_INVALID_URI;
+ quoted_name = g_shell_quote(name);
- /* FIXME: escape for shell */
- cmd = g_strdup_printf ("rm -rf '%s'", name);
+ cmd = g_strdup_printf ("rm -rf %s", quoted_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
g_free (name);
+ g_free (quoted_name);
if (result != GNOME_VFS_OK) {
return result;
@@ -652,13 +751,15 @@
char *cmd = NULL;
GnomeVFSResult result;
gchar *name;
+ gchar *quoted_name;
+ DEBUG("begin");
name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
if (name == NULL)
return GNOME_VFS_ERROR_INVALID_URI;
+ quoted_name = g_shell_quote (name);
- /* FIXME: escape for shell */
- cmd = g_strdup_printf ("rm -rf '%s'", name);
+ cmd = g_strdup_printf ("rm -rf %s", quoted_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
g_free (name);
@@ -684,6 +785,7 @@
GnomeVFSResult result=GNOME_VFS_OK;
gchar *full_name;
+ DEBUG("begin");
full_name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
if (full_name == NULL)
return GNOME_VFS_ERROR_INVALID_URI;
@@ -692,6 +794,8 @@
char *encoded_dir;
char *dir;
char *new_name;
+ char *quoted_full_name;
+ char *quoted_new_name;
encoded_dir = gnome_vfs_uri_extract_dirname (uri);
dir = gnome_vfs_unescape_string (encoded_dir, G_DIR_SEPARATOR_S);
@@ -710,32 +814,35 @@
}
/* FIXME: escape for shell */
- cmd = g_strdup_printf ("mv '%s' '%s'", full_name,
- new_name);
+ quoted_new_name = g_shell_quote(new_name);
+ quoted_full_name = g_shell_quote(full_name);
+ cmd = g_strdup_printf ("mv %s %s", quoted_full_name,
+ quoted_new_name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
g_free (dir);
g_free (new_name);
+ g_free (quoted_new_name);
+ g_free (quoted_full_name);
+ g_free (full_name);
+
+ if (result != GNOME_VFS_OK) {
+ return result;
+ }
/* Read all info from remote host */
while (1) {
char c;
GnomeVFSResult res;
- GnomeVFSFileSize j;
- res = ssh_read (handle, &c, 1, &j);
- if (j == 0 || res != GNOME_VFS_OK)
+ GnomeVFSFileSize bytes_read;
+ res = ssh_read (handle, &c, 1, &bytes_read);
+ if (bytes_read == 0 || res != GNOME_VFS_OK)
break;
}
ssh_destroy (handle);
-
- if (result != GNOME_VFS_OK) {
- g_free (full_name);
- return result;
- }
}
- g_free (full_name);
return result;
}
@@ -745,6 +852,7 @@
GnomeVFSFileInfo *file_info,
GnomeVFSFileInfoOptions options)
{
+ DEBUG();
return GNOME_VFS_ERROR_WRONG_FORMAT;
}
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]