ssh-method patch
- From: Robert Mibus <mibus bigpond com>
- To: Desktop Devel List <desktop-devel-list gnome org>
- Cc: gnome-vfs ximian com
- Subject: ssh-method patch
- Date: 04 May 2002 22:27:21 +0930
Attatched is a patch against CVS (HEAD IIRC*)
gnome-vfs/modules/ssh-method.c.
It basically brings it up to a usable state.
I've implemented unlink, mkdir, rmdir, and set_file_info.
I've also fixed buglets in much of the rest of it.
(Though it still has a problem with directories sometimes appearing
empty).
Known problems:
* Running out of (remote) space will hang a copy to the remote location
* it uses commands over an ssh link, which seems hacky to me.
(that's how it was originally written, I don't know if there's a
libscp or anything).
* it needs a vaguely bashish shell on the remote side (it runs 'ls -ld
[file] 2>&1' so it gets stderr as well as stdout).
* I wrote it ;-P
But in any case, it's usable enough for me to copy MP3s to my linux iPAQ
:-D
Now: Could someone with CVS access please look the patch over and (if
good enough) commit it?
Thanks greatly;
mibus
* whatever v-b-s pulls
--
Robert Mibus <mibus bigpond com>
"Bother," said Pooh.
"Eeyore, ready two photon torpedoes and lock phasers on the Heffalump;
Piglet, meet me in transporter room three."
--- ssh-method.c.orig Sat May 4 13:39:56 2002
+++ ssh-method.c Sat May 4 22:13:53 2002
@@ -93,6 +93,21 @@
GnomeVFSFileInfo *file_info,
GnomeVFSFileInfoOptions options,
GnomeVFSContext *context);
+static GnomeVFSResult do_make_directory (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ guint perm,
+ GnomeVFSContext *context);
+static GnomeVFSResult do_remove_directory(GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ GnomeVFSContext *context);
+static GnomeVFSResult do_unlink (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ GnomeVFSContext *context);
+static GnomeVFSResult do_set_file_info (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ const GnomeVFSFileInfo *info,
+ GnomeVFSSetFileInfoMask mask,
+ GnomeVFSContext *context);
#if 0
static GnomeVFSResult do_get_file_info_from_handle
(GnomeVFSMethodHandle *method_handle,
@@ -118,11 +133,12 @@
do_get_file_info,
NULL, /* get_file_info_from_handle */
do_is_local,
- NULL, /* make directory */
- NULL, /* remove directory */
- NULL, /* unlink */
+ do_make_directory, /* make directory */
+ do_remove_directory, /* remove directory */
+ NULL, /* move */
+ do_unlink, /* unlink */
NULL, /* check_same_fs */
- NULL, /* set_file_info */
+ do_set_file_info, /* set_file_info */
NULL, /* truncate */
NULL, /* find_directory */
NULL /* create_symbolic_link */
@@ -175,7 +191,7 @@
if (status != 0) {
return gnome_vfs_result_from_errno ();
- }*/
+ } */
}
@@ -210,8 +226,9 @@
GnomeVFSFileSize *bytes_read)
{
GnomeVFSFileSize my_read;
+
my_read = (GnomeVFSFileSize) read (handle->read_fd, buffer,
- (size_t) num_bytes);
+ (size_t) num_bytes);
if (my_read == -1) {
return gnome_vfs_result_from_errno ();
@@ -229,8 +246,17 @@
GnomeVFSFileSize *bytes_written)
{
GnomeVFSFileSize written;
- written = (GnomeVFSFileSize) write (handle->write_fd, buffer,
- (size_t) num_bytes);
+ int count=0;
+
+ do {
+ errno = 0;
+ written = (GnomeVFSFileSize) write (handle->write_fd, buffer,
+ (size_t) num_bytes);
+ if (written == -1 && errno == EINTR) {
+ count++;
+ usleep (10);
+ }
+ } while (written == -1 && errno == EINTR && count < 5);
if (written == -1) {
return gnome_vfs_result_from_errno ();
@@ -291,20 +317,27 @@
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'\n", uri->text);
+ cmd = g_strdup_printf ("cat '%s'", name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
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;
}
@@ -312,6 +345,8 @@
handle->type = SSH_FILE;
*method_handle = (GnomeVFSMethodHandle *)handle;
+ g_free (name);
+
return result;
}
@@ -327,18 +362,24 @@
SshHandle *handle = NULL;
char *cmd;
GnomeVFSResult result;
+ char *name;
+
+ /* FIXME: escape for shell */
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
if (mode != GNOME_VFS_OPEN_WRITE) {
+ g_free (name);
return GNOME_VFS_ERROR_INVALID_OPEN_MODE;
}
/* FIXME: escape for shell */
- cmd = g_strdup_printf ("cat > '%s'\n", uri->text);
+ cmd = g_strdup_printf ("cat > '%s'", name);
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
if (result != GNOME_VFS_OK) {
+ g_free (name);
return result;
}
@@ -348,6 +389,7 @@
handle->type = SSH_FILE;
*method_handle = (GnomeVFSMethodHandle *)handle;
+ g_free (name);
return result;
}
@@ -396,10 +438,16 @@
SshHandle *handle = NULL;
char *cmd = NULL;
GnomeVFSResult result;
+ char *name;
/* FIXME: escape for shell */
- cmd = g_strdup_printf ("ls -l '%s'", uri->text);
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ if (strlen (name))
+ cmd = g_strdup_printf ("ls -l '%s'", name);
+ else
+ cmd = g_strdup_printf ("ls -l '/'");
result = ssh_connect (&handle, uri, cmd);
+ g_free (name);
g_free (cmd);
if (result != GNOME_VFS_OK) {
@@ -436,16 +484,17 @@
int i=0;
GnomeVFSFileSize j;
struct stat st;
- char *filename, *linkname;
+ char *tempfilename, *filename, *linkname;
for (;;) {
+ tempfilename = NULL;
filename = NULL;
linkname = NULL;
i = 0;
j = 0;
+
while (i<LINE_LENGTH) {
result = ssh_read ((SshHandle *)method_handle, &c, 1, &j);
-
if (j == 0 || c == '\r' || c == '\n') {
break;
}
@@ -459,15 +508,24 @@
}
line[i] = 0;
-
if (i == 0) {
return GNOME_VFS_ERROR_EOF;
}
- if (!gnome_vfs_parse_ls_lga (line, &st, &filename, &linkname)) {
+ if (!gnome_vfs_parse_ls_lga (line, &st, &tempfilename, &linkname)) {
+ /* Maybe the file doesn't exist? */
+ if (strstr(line, "No such file or directory"))
+ return GNOME_VFS_ERROR_NOT_FOUND;
continue; /* skip to next line */
}
+ /* Get rid of the path */
+ if (strrchr(tempfilename, '/'))
+ filename = g_strdup(strrchr(tempfilename,'/')+1);
+ else
+ filename = g_strdup(tempfilename);
+ g_free (tempfilename);
+
gnome_vfs_stat_to_file_info (file_info, &st);
file_info->name = filename;
if (linkname) {
@@ -485,6 +543,10 @@
file_info->valid_fields &=
~GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE;
+ /* Break out.
+ We are in a loop so we get the first 'ls' line;
+ often it starts with 'total 2213' etc.
+ */
break;
}
@@ -501,11 +563,17 @@
SshHandle *handle = NULL;
char *cmd = NULL;
GnomeVFSResult result;
+ char *name;
/* FIXME: escape for shell */
- cmd = g_strdup_printf ("ls -ld '%s'", uri->text);
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ if (strlen (name))
+ cmd = g_strdup_printf ("ls -ld '%s' 2>&1", name);
+ else
+ cmd = g_strdup_printf ("ls -ld '/' 2>&1");
result = ssh_connect (&handle, uri, cmd);
g_free (cmd);
+ g_free (name);
if (result != GNOME_VFS_OK) {
return result;
@@ -515,10 +583,164 @@
handle->type = SSH_LIST;
result = do_read_directory (method, (GnomeVFSMethodHandle *)handle,
- file_info, context);
+ file_info, context);
+
+ ssh_destroy (handle);
+
+ return (result == GNOME_VFS_ERROR_EOF ? GNOME_VFS_OK : result);
+}
+
+static GnomeVFSResult
+do_make_directory (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ guint perm,
+ GnomeVFSContext *context)
+{
+ SshHandle *handle = NULL;
+ char *cmd = NULL;
+ GnomeVFSResult result;
+ char *name;
+
+ /* FIXME: escape for shell */
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+
+ /* FIXME: escape for shell */
+ cmd = g_strdup_printf ("mkdir '%s'", name);
+ result = ssh_connect (&handle, uri, cmd);
+ g_free (cmd);
+ g_free (name);
+
+ if (result != GNOME_VFS_OK) {
+ return result;
+ }
ssh_destroy (handle);
+ return result;
+}
+
+static GnomeVFSResult
+do_remove_directory (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ GnomeVFSContext *context)
+{
+ SshHandle *handle = NULL;
+ char *cmd = NULL;
+ GnomeVFSResult result;
+ gchar *name;
+
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ if (name == NULL)
+ return GNOME_VFS_ERROR_INVALID_URI;
+
+ /* FIXME: escape for shell */
+ cmd = g_strdup_printf ("rm -rf '%s'", name);
+ result = ssh_connect (&handle, uri, cmd);
+ g_free (cmd);
+ g_free (name);
+
+ if (result != GNOME_VFS_OK) {
+ return result;
+ }
+
+ ssh_destroy (handle);
+
+ return result;
+}
+
+GnomeVFSResult
+do_unlink (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ GnomeVFSContext *contet)
+{
+ SshHandle *handle = NULL;
+ char *cmd = NULL;
+ GnomeVFSResult result;
+ gchar *name;
+
+ name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ if (name == NULL)
+ return GNOME_VFS_ERROR_INVALID_URI;
+
+ /* FIXME: escape for shell */
+ cmd = g_strdup_printf ("rm -rf '%s'", name);
+ result = ssh_connect (&handle, uri, cmd);
+ g_free (cmd);
+ g_free (name);
+
+ if (result != GNOME_VFS_OK) {
+ return result;
+ }
+
+ ssh_destroy (handle);
+
+ return result;
+}
+
+static GnomeVFSResult
+do_set_file_info (GnomeVFSMethod *method,
+ GnomeVFSURI *uri,
+ const GnomeVFSFileInfo *info,
+ GnomeVFSSetFileInfoMask mask,
+ GnomeVFSContext *context)
+{
+ SshHandle *handle = NULL;
+ char *cmd = NULL;
+ GnomeVFSResult result=GNOME_VFS_OK;
+ gchar *full_name;
+
+ full_name = gnome_vfs_unescape_string (uri->text, G_DIR_SEPARATOR_S);
+ if (full_name == NULL)
+ return GNOME_VFS_ERROR_INVALID_URI;
+
+ if (mask & GNOME_VFS_SET_FILE_INFO_NAME) {
+ char *encoded_dir;
+ char *dir;
+ char *new_name;
+
+ encoded_dir = gnome_vfs_uri_extract_dirname (uri);
+ dir = gnome_vfs_unescape_string (encoded_dir, G_DIR_SEPARATOR_S);
+ g_free (encoded_dir);
+ g_assert (dir != NULL);
+
+ /* FIXME bugzilla.eazel.com 645: This needs to return
+ * an error for incoming names with "/" characters in
+ * them, instead of moving the file.
+ */
+
+ if (dir[strlen(dir) - 1] != '/') {
+ new_name = g_strconcat (dir, "/", info->name, NULL);
+ } else {
+ new_name = g_strconcat (dir, info->name, NULL);
+ }
+
+ /* FIXME: escape for shell */
+ cmd = g_strdup_printf ("mv '%s' '%s'", full_name,
+ new_name);
+ result = ssh_connect (&handle, uri, cmd);
+ g_free (cmd);
+ g_free (dir);
+ g_free (new_name);
+
+ /* 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)
+ 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]