Index: modules/sftp-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/sftp-method.c,v
retrieving revision 1.34
diff -u -r1.34 sftp-method.c
--- modules/sftp-method.c	8 May 2005 13:04:05 -0000	1.34
+++ modules/sftp-method.c	10 May 2005 12:03:53 -0000
@@ -1736,6 +1736,73 @@
 	return GNOME_VFS_OK;
 }
 
+static GnomeVFSResult
+get_link_target (SftpConnection *conn,
+		 const gchar    *link_path,
+		 gchar          **target)
+{
+	Buffer msg;
+	guint type, recv_id, count, id;
+	guint status;
+	GnomeVFSResult res;
+
+	id = sftp_connection_get_id (conn);
+
+	iobuf_send_string_request (conn->out_fd, id, SSH2_FXP_READLINK,
+				   link_path, strlen (link_path));
+
+	buffer_init (&msg);
+
+	res = buffer_recv (&msg, conn->in_fd);
+	if (res != GNOME_VFS_OK) {
+		g_critical ("Error receiving message: %d", res);
+		buffer_free (&msg);
+		return res;
+	}
+
+	type = buffer_read_gchar (&msg);
+	recv_id = buffer_read_gint32 (&msg);
+
+	if (type == SSH2_FXP_STATUS) {
+		status = buffer_read_gint32 (&msg);
+		buffer_free (&msg);
+		*target = NULL;
+		DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: Bad status (%d).",
+			      __FUNCTION__, status));
+		return sftp_status_to_vfs_result (status);
+	}
+	else if (recv_id != id || type != SSH2_FXP_NAME) {
+		DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: Bad message id or type (%d, %d).",
+			      __FUNCTION__, recv_id, type));
+		buffer_free (&msg);
+		return GNOME_VFS_ERROR_PROTOCOL_ERROR;
+	}
+
+	count = buffer_read_gint32 (&msg);
+
+	if (count == 0) {
+		DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: File not found: %s",
+			      __FUNCTION__, path));
+		buffer_free (&msg);
+		return GNOME_VFS_ERROR_NOT_FOUND;
+	}
+	else if (count != 1) {
+		DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: Bad count (%d).",
+			      __FUNCTION__, count));
+		buffer_free (&msg);
+		return GNOME_VFS_ERROR_PROTOCOL_ERROR;
+	}
+
+	*target = buffer_read_string (&msg, NULL);
+
+	buffer_free (&msg);
+
+	DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "Link target is %s", *target));
+
+	return GNOME_VFS_OK;
+}
+
+
 static GnomeVFSResult 
 do_open (GnomeVFSMethod        *method,
 	 GnomeVFSMethodHandle **method_handle,
@@ -2326,6 +2393,8 @@
 			sftp_connection_unlock (conn);
 			return res;
 		}
+
+		g_free (path);
 	}
 	else
 		real_path = path;
@@ -2341,13 +2410,8 @@
 	else
 		file_info->name = g_path_get_basename (path);
 
-	g_free (path);
-
 	res = iobuf_read_file_info (conn->in_fd, file_info, id);
  
-	sftp_connection_unref (conn);
-	sftp_connection_unlock (conn);
-
 	if (res == GNOME_VFS_OK) {
 		if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR)
 			file_info->mime_type
@@ -2359,6 +2423,18 @@
 
 		file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE;
 	}
+
+	if (!(options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) &&
+	    file_info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK) {
+		res = get_link_target (conn,
+				       real_path,
+				       &file_info->symlink_name);
+	}
+
+	sftp_connection_unref (conn);
+	sftp_connection_unlock (conn);
+
+	g_free (real_path);
 
 	DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: Exit", __FUNCTION__));
 
