Re: 2.0.2 released ...



Here is the patch for the ssh and ftp modules

Le lun 16/09/2002 à 11:51, Christophe Fergeau a écrit :
> And here is the corresponding patch for the doc
> 
> Le lun 16/09/2002 à 11:42, Christophe Fergeau a écrit :
> > The attached file should contains the patch which diff adds the
> > "uses_gnomevfs" key to the .application files. I'll post a patch with
> > the changes I made to the ssh and ftp modules later, I noticed I have to
> > clean it up a little first.
> > Btw you are a good ximian employee, asking me to resend those patches
> > made me switch from sylpheed to evolution since the patches were lost in
> > thousands of emails and I couldn't find them with sylpheed :)
> > 
> > Christophe
> > 
> > Le lun 16/09/2002 à 11:51, Michael Meeks a écrit :
> > > Hi Christophe,
> > > 
> > > 	Since we've released 2.0.2, it'd be really great to see your patches
> > > again, so we can get them in ASAP ... do you have pointers to them
> > > somewhere ?
> > > 
> > > 	Regards,
> > > 
> > > 		Michael.
> > > 
> > > -- 
> > >  mmeeks gnu org  <><, Pseudo Engineer, itinerant idiot
> > > 
> > > _______________________________________________
> > > gnome-vfs-list mailing list
> > > gnome-vfs-list gnome org
> > > http://mail.gnome.org/mailman/listinfo/gnome-vfs-list
> > 
> > 
> > 
> > 
> > 
> > ----
> > 
> 
> > ? gnomevfs.diff
> > ? gnomevfs2.diff
> > ? modules/applications.vfolder-info
> > ? modules/preferences.vfolder-info
> > ? modules/vfolder
> > Index: libgnomevfs/gnome-vfs-application-registry.c
> > ===================================================================
> > RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-application-registry.c,v
> > retrieving revision 1.21
> > diff -u -r1.21 gnome-vfs-application-registry.c
> > --- libgnomevfs/gnome-vfs-application-registry.c	29 May 2002 00:43:47 -0000	1.21
> > +++ libgnomevfs/gnome-vfs-application-registry.c	26 Aug 2002 12:58:50 -0000
> > @@ -27,7 +27,7 @@
> >  
> >  #include "config.h"
> >  #include "gnome-vfs-application-registry.h"
> > -
> > +#include "gnome-vfs-configuration.h"
> >  #include "gnome-vfs-mime-handlers.h"
> >  #include "gnome-vfs-mime-private.h"
> >  #include "gnome-vfs-mime.h"
> > @@ -705,7 +705,7 @@
> >  	Application *application;
> >  	char *key;
> >  	char *lang;
> > -	
> > +
> >  	fp = fopen (filename, "r");
> >  	if (fp == NULL)
> >  		return;
> > @@ -1594,7 +1594,8 @@
> >  						    const char *uri_scheme)
> >  {
> >  	Application *application;
> > -
> > +	gboolean uses_gnomevfs;
> > +	
> >  	g_return_val_if_fail (app_id != NULL, FALSE);
> >  	g_return_val_if_fail (uri_scheme != NULL, FALSE);
> >  
> > @@ -1604,7 +1605,10 @@
> >  	if (application == NULL)
> >  		return FALSE;
> >  
> > +	uses_gnomevfs = real_get_bool_value (application, GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS, NULL);
> > +
> >  	if (strcmp (uri_scheme, "file") == 0 &&
> > +	    uses_gnomevfs == FALSE &&
> >  	    application->supported_uri_schemes == NULL &&
> >  	    application->user_application->supported_uri_schemes == NULL) {
> >  		return TRUE;
> > @@ -1624,6 +1628,21 @@
> >  				 (GCompareFunc) strcmp) != NULL)) {
> >  		return TRUE;
> >  	}
> > +	/* check in the list of uris supported by gnome-vfs if necessary */
> > +	else if (uses_gnomevfs) {
> > +		GList *supported_uris;
> > +		gboolean res;
> > +		
> > +		supported_uris = gnome_vfs_configuration_get_methods_list();
> > +		res = (g_list_find_custom(supported_uris,
> > +					  /*glib is const incorrect*/(gpointer) uri_scheme,
> > +					  (GCompareFunc) strcmp) != NULL);
> > +
> > +		g_list_foreach(supported_uris, (GFunc) g_free, NULL);
> > +		g_list_free(supported_uris);
> > +
> > +		return res;
> > +	}
> >  
> >  	return FALSE;
> >  }
> > @@ -1851,6 +1870,7 @@
> >  {
> >  	Application *i_application;
> >  	GnomeVFSMimeApplication *application;
> > +	gboolean uses_gnomevfs = FALSE;
> >  
> >  	g_return_val_if_fail (app_id != NULL, NULL);
> >  
> > @@ -1888,6 +1908,29 @@
> >  			(i_application,
> >  			 GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL,
> >  			 NULL);
> > +
> > +	uses_gnomevfs = real_get_bool_value (i_application, GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS, NULL);
> > +
> > +	if (uses_gnomevfs) {
> > +		GList *methods_list = 
> > +			gnome_vfs_configuration_get_methods_list();
> > +		GList *l;
> > +		if (application->expects_uris == GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_PATHS) {
> > +			application->expects_uris = GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS;
> > +		}
> > +		for (l = methods_list; l != NULL; l = l->next) {
> > +			if (g_list_find_custom (application->supported_uri_schemes,
> > +						/*glib is const incorrect*/(gpointer) l->data,
> > +						(GCompareFunc) strcmp) == NULL) {
> > +				application->supported_uri_schemes = 
> > +					g_list_prepend(application->supported_uri_schemes, 
> > +						       l->data);
> > +			} else {
> > +				g_free(l->data);
> > +			}			
> > +		}
> > +		g_list_free(methods_list);
> > +	}	
> >  
> >  	return application;
> >  }
> > Index: libgnomevfs/gnome-vfs-application-registry.h
> > ===================================================================
> > RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-application-registry.h,v
> > retrieving revision 1.9
> > diff -u -r1.9 gnome-vfs-application-registry.h
> > --- libgnomevfs/gnome-vfs-application-registry.h	3 Aug 2001 00:39:58 -0000	1.9
> > +++ libgnomevfs/gnome-vfs-application-registry.h	26 Aug 2002 12:58:50 -0000
> > @@ -39,6 +39,7 @@
> >  /* These are the standard boolean keys to get */
> >  #define GNOME_VFS_APPLICATION_REGISTRY_CAN_OPEN_MULTIPLE_FILES "can_open_multiple_files"
> >  #define GNOME_VFS_APPLICATION_REGISTRY_REQUIRES_TERMINAL "requires_terminal"
> > +#define GNOME_VFS_APPLICATION_REGISTRY_USES_GNOMEVFS "uses_gnomevfs"
> >  	
> >  /*
> >   * Existance check
> > Index: libgnomevfs/gnome-vfs-configuration.c
> > ===================================================================
> > RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-configuration.c,v
> > retrieving revision 1.18
> > diff -u -r1.18 gnome-vfs-configuration.c
> > --- libgnomevfs/gnome-vfs-configuration.c	28 Jan 2002 19:10:07 -0000	1.18
> > +++ libgnomevfs/gnome-vfs-configuration.c	26 Aug 2002 12:58:50 -0000
> > @@ -554,3 +554,28 @@
> >  		*args = element->args;
> >  	return element->path;
> >  }
> > +
> > +static void
> > +add_method_to_list(const gchar *key, gpointer value, GList **methods_list)
> > +{
> > +	*methods_list = g_list_append(*methods_list, g_strdup(key));
> > +}
> > +
> > +GList *
> > +gnome_vfs_configuration_get_methods_list (void)
> > +{
> > +	GList *methods_list = NULL;
> > +
> > +	G_LOCK (configuration);
> > +	if (configuration != NULL) {
> > +		maybe_reload ();
> > +		g_hash_table_foreach(configuration->method_to_module_path, 
> > +				     (GHFunc)add_method_to_list, &methods_list);
> > +	} else {
> > +		/* This should never happen.  */
> > +		methods_list = NULL;
> > +	}
> > +
> > +	G_UNLOCK (configuration);
> > +	return methods_list;
> > +}
> > Index: libgnomevfs/gnome-vfs-configuration.h
> > ===================================================================
> > RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-configuration.h,v
> > retrieving revision 1.4
> > diff -u -r1.4 gnome-vfs-configuration.h
> > --- libgnomevfs/gnome-vfs-configuration.h	3 Aug 2001 00:39:58 -0000	1.4
> > +++ libgnomevfs/gnome-vfs-configuration.h	26 Aug 2002 12:58:50 -0000
> > @@ -25,6 +25,7 @@
> >  #define GNOME_VFS_CONFIGURATION_H
> >  
> >  #include <glib/gtypes.h>
> > +#include <glib/glist.h>
> >  
> >  G_BEGIN_DECLS
> >  
> > @@ -32,6 +33,8 @@
> >  gboolean     gnome_vfs_configuration_init            (void);
> >  void         gnome_vfs_configuration_uninit          (void);
> >  const gchar *gnome_vfs_configuration_get_module_path (const gchar *method_name, const char ** args);
> > +GList       *gnome_vfs_configuration_get_methods_list(void);
> > +
> >  
> >  G_END_DECLS
> >  
> 
> 
> ----
> 

> diff -ru gnome-vfs/doc/mime-data-specification.txt gnome-vfs-new/doc/mime-data-specification.txt
> --- gnome-vfs/doc/mime-data-specification.txt	2001-05-02 00:14:18.000000000 +0200
> +++ gnome-vfs-new/doc/mime-data-specification.txt	2002-08-21 23:56:13.000000000 +0200
> @@ -402,10 +402,11 @@
>     for some known applications that support "http" scheme URIs and
>     local file paths, but not "file" scheme URIs.)
>  
> -5. [to be implemented] all_gnome_vfs_schemes_supported: If "true", all
> -   gnome-vfs schemes should be included in the set of "supported
> -   schemes". Other schemes can be added by also including a
> -   supported_uri_schemes key as well.  
> +5. uses_gnomevfs: If "true", all gnome-vfs schemes should be included 
> +   in the set of "supported schemes". Other schemes can be added by 
> +   also including a supported_uri_schemes key as well. When this key
> +   is "true", if expects_uris is "false", it is automatically set to
> +   "true".
>  
>  [may want to discuss issue of using cover scripts to make programs
>  easily invokable rather than teaching clients to pass command-line

? gnome-vfs.diff
? login.diff
? modules.diff
? modules/vfolder
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.1334.2.48
diff -u -r1.1334.2.48 ChangeLog
--- ChangeLog	13 Sep 2002 13:39:18 -0000	1.1334.2.48
+++ ChangeLog	16 Sep 2002 14:48:02 -0000
@@ -1,3 +1,15 @@
+2002-09-16  Christophe Fergeau <teuf users sourceforge net>
+	* modules/ftp-method.c: fixed do_read to correctly report EOF when
+	  read return 0, moved the login code to a separate function to 
+	  make it easier to try to login several times when the
+	  call to an authentification callback in in place
+	 * modules/ssh-method.c: fixed do_read to correctly report EOF when
+	   read return 0, correctly reports "login failed" if the remote site
+	   expected a password (which is not handled right now), fixed a 
+	   buffer overflow, fixed connection when no username was specified
+	   or when the locale wasn't C, escape the filenames passed to the
+	   shell using glib
+
 2002-09-13  Ghee Teo <ghee teo sun com>
 	* Fixes #92132 in modules/http-method.c which leaks file descriptor
 	  on a bad page, error 405.
Index: modules/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
--- modules/ftp-method.c	8 May 2002 19:04:51 -0000	1.87
+++ modules/ftp-method.c	16 Sep 2002 14:48:02 -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,32 @@
 
 }
 
+
+static GnomeVFSResult ftp_login(FtpConnection *conn, 
+                                const char *user, const char *password)
+{
+	gchar *tmpstring;
+	GnomeVFSResult 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", password);
+		result = do_basic_command (conn, tmpstring);
+		g_free (tmpstring);
+	}
+
+	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 +596,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 +607,7 @@
 		gnome_vfs_uri_unref (conn->uri);
 		g_string_free (conn->response_buffer, TRUE);
 		g_free (conn);
+			
 		return result;
 	}
 
@@ -785,7 +801,7 @@
 gboolean 
 do_is_local (GnomeVFSMethod *method, 
 	     const GnomeVFSURI *uri)
-{
+{	
 	return FALSE;
 }
 
@@ -860,7 +876,7 @@
 	 GnomeVFSContext *context) 
 {
 	FtpConnection *conn = (FtpConnection * )method_handle;
-
+	GnomeVFSResult result;
 #if 0
 	/*
 	if (conn->operation != FTP_READ) {
@@ -870,7 +886,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: modules/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
--- modules/ssh-method.c	19 Jul 2002 07:57:11 -0000	1.8.2.1
+++ modules/ssh-method.c	16 Sep 2002 14:48:02 -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,8 @@
 #include <unistd.h>
 #include <signal.h>
 
+#define LINE_LENGTH 4096 /* max line length we'll grok */
+
 typedef struct {
 	GnomeVFSMethodHandle method_handle;
 	GnomeVFSURI *uri;
@@ -47,6 +48,7 @@
 	GnomeVFSOpenMode open_mode;
 	int read_fd;
 	int write_fd;
+	int error_fd;
 	pid_t pid;
 } SshHandle;
 
@@ -145,6 +147,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 +235,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 +264,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 +353,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 +382,23 @@
 	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);
 
 	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 +406,7 @@
 	handle->type = SSH_FILE;
 	*method_handle = (GnomeVFSMethodHandle *)handle;
 
-	g_free (name);
-
-	return result;
+	return GNOME_VFS_OK;
 }
 
 static GnomeVFSResult   
@@ -351,33 +422,30 @@
 	char *cmd;
 	GnomeVFSResult result;
 	char *name;
-
-	/* FIXME: escape for shell */
-	name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+	char *quoted_name;
 
 	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;
 }
 
@@ -397,8 +465,14 @@
 	 GnomeVFSFileSize *bytes_read,
 	 GnomeVFSContext *context)
 {
-	return ssh_read ((SshHandle *)method_handle, buffer, num_bytes,
-			bytes_read);
+	GnomeVFSResult result;
+
+	result =  ssh_read ((SshHandle *)method_handle, buffer, num_bytes,
+		  	    bytes_read);
+	if (*bytes_read == 0) {	
+		result = GNOME_VFS_ERROR_EOF;
+	}
+	return result;
 }
 
 /* alternative impl:
@@ -427,17 +501,19 @@
 	char *cmd = NULL;
 	GnomeVFSResult result;
 	char *name;
+	char *quoted_name;
 
-	/* FIXME: escape for shell */
 	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);
 
@@ -449,7 +525,6 @@
 	handle->type = SSH_LIST;
 	*method_handle = (GnomeVFSMethodHandle *)handle;
 
-	return result;
 	return GNOME_VFS_OK;
 }
 
@@ -461,8 +536,6 @@
 	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,10 +543,10 @@
 		   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;
 
@@ -482,11 +555,12 @@
 		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 +571,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 +631,13 @@
 	char *cmd = NULL;
 	GnomeVFSResult result;
 	char *name;
+	char *quoted_name;
 
-	/* FIXME: escape for shell */
 	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,6 +645,7 @@
 	result = ssh_connect (&handle, uri, cmd);
 	g_free (cmd);
 	g_free (name);
+	g_free (quoted_name);
 
 	if (result != GNOME_VFS_OK) {
 		return result;
@@ -595,12 +672,12 @@
 	char *cmd = NULL;
 	GnomeVFSResult result;
 	char *name;
+	char *quoted_name;
 
-	/* FIXME: escape for shell */
 	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 +700,18 @@
 	char *cmd = NULL;
 	GnomeVFSResult result;
 	gchar *name;
+	gchar *quoted_name;
 
 	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 +731,14 @@
 	char *cmd = NULL;
 	GnomeVFSResult result;
 	gchar *name;
+	gchar *quoted_name;
 
 	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);
@@ -692,6 +772,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 +792,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;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]