Index: libgnomevfs/gnome-vfs-file-info.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-file-info.h,v
retrieving revision 1.38
diff -u -p -r1.38 gnome-vfs-file-info.h
--- libgnomevfs/gnome-vfs-file-info.h	22 Jun 2006 12:10:36 -0000	1.38
+++ libgnomevfs/gnome-vfs-file-info.h	16 Jul 2006 05:56:48 -0000
@@ -377,6 +377,7 @@ typedef enum {
  * @GNOME_VFS_SET_FILE_INFO_OWNER: change the file's owner
  * @GNOME_VFS_SET_FILE_INFO_TIME: change the file's time stamp(s)
  * @GNOME_VFS_SET_FILE_INFO_ACL: change the file's ACLs
+ * @GNOME_VFS_SET_FILE_INFO_SYMLINK_NAME: change the file's symlink name
  *
  * Packed boolean bitfield representing the aspects of the file
  * to be changed in a gnome_vfs_set_file_info() call.
@@ -389,7 +390,8 @@ typedef enum {
 	GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2,
 	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3,
 	GNOME_VFS_SET_FILE_INFO_ACL = 1 << 4,
-	GNOME_VFS_SET_FILE_INFO_SELINUX_CONTEXT = 1 << 5
+	GNOME_VFS_SET_FILE_INFO_SELINUX_CONTEXT = 1 << 5,
+	GNOME_VFS_SET_FILE_INFO_SYMLINK_NAME = 1 << 6
 } GnomeVFSSetFileInfoMask;
 
 
Index: libgnomevfs/gnome-vfs-result.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-result.c,v
retrieving revision 1.34
diff -u -p -r1.34 gnome-vfs-result.c
--- libgnomevfs/gnome-vfs-result.c	14 Jul 2006 16:19:18 -0000	1.34
+++ libgnomevfs/gnome-vfs-result.c	16 Jul 2006 05:56:50 -0000
@@ -89,7 +89,8 @@ static char *status_strings[] = {
 	/* GNOME_VFS_ERROR_NAMESERVER */                N_("Nameserver error"),
  	/* GNOME_VFS_ERROR_LOCKED */			N_("The resource is locked"),
 	/* GNOME_VFS_ERROR_DEPRECATED_FUNCTION */       N_("Function call deprecated"),
-	/* GNOME_VFS_ERROR_INVALID_FILENAME */		N_("Invalid filename")
+	/* GNOME_VFS_ERROR_INVALID_FILENAME */		N_("Invalid filename"),
+	/* GNOME_VFS_ERROR_NOT_A_SYMBOLIC_LINK */	N_("Not a symbolic link")
 };
 
 /**
Index: libgnomevfs/gnome-vfs-result.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-result.h,v
retrieving revision 1.14
diff -u -p -r1.14 gnome-vfs-result.h
--- libgnomevfs/gnome-vfs-result.h	14 Jul 2006 14:34:15 -0000	1.14
+++ libgnomevfs/gnome-vfs-result.h	16 Jul 2006 05:56:50 -0000
@@ -87,6 +87,7 @@ G_BEGIN_DECLS
  * @GNOME_VFS_ERROR_LOCKED: The resource is locked.
  * @GNOME_VFS_ERROR_DEPRECATED_FUNCTION: Function call deprecated.
  * @GNOME_VFS_ERROR_INVALID_FILENAME: The specified filename is invalid.
+ * @GNOME_VFS_ERROR_NOT_A_SYMBOLIC_LINK: Not a symbolic link.
  *
  * A #GnomeVFSResult informs library clients about the result of a file operation.
  * Unless it is #GNOME_VFS_OK, it denotes that a problem occurred and the operation
@@ -146,6 +147,7 @@ typedef enum {
 	GNOME_VFS_ERROR_LOCKED,
 	GNOME_VFS_ERROR_DEPRECATED_FUNCTION,
 	GNOME_VFS_ERROR_INVALID_FILENAME,
+	GNOME_VFS_ERROR_NOT_A_SYMBOLIC_LINK,
 	GNOME_VFS_NUM_ERRORS
 } GnomeVFSResult;
 
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.159
diff -u -p -r1.159 file-method.c
--- modules/file-method.c	13 Jun 2006 16:47:55 -0000	1.159
+++ modules/file-method.c	16 Jul 2006 05:57:02 -0000
@@ -2139,6 +2139,42 @@ rename_helper (const gchar *old_full_nam
 }
 
 static GnomeVFSResult
+set_symlink_name_helper (const gchar *full_name,
+			 const GnomeVFSFileInfo *info)
+{
+#ifndef G_OS_WIN32
+	struct stat statbuf;
+
+	if (info->symlink_name == NULL ||
+	    !(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME)) {
+		return GNOME_VFS_ERROR_BAD_PARAMETERS;
+	}
+
+	if (g_lstat (full_name, &statbuf) != 0) {
+		return gnome_vfs_result_from_errno ();
+	}
+
+	if (!S_ISLNK (statbuf.st_mode)) {
+		return GNOME_VFS_ERROR_NOT_A_SYMBOLIC_LINK;
+	}
+
+	if (g_unlink (full_name) != 0) {
+		return gnome_vfs_result_from_errno ();
+	}
+
+	if (symlink (info->symlink_name, full_name) != 0) {
+		/* TODO should we try to restore the old symlink? */
+		return gnome_vfs_result_from_errno ();
+	}
+
+	return GNOME_VFS_OK;
+#else
+	return GNOME_VFS_ERROR_NOT_SUPPORTED;
+#endif
+
+}
+
+static GnomeVFSResult
 do_move (GnomeVFSMethod *method,
 	 GnomeVFSURI *old_uri,
 	 GnomeVFSURI *new_uri,
@@ -2399,7 +2435,16 @@ do_set_file_info (GnomeVFSMethod *method
 			return result;	
 		}
 	}
-	
+
+	if (mask & GNOME_VFS_SET_FILE_INFO_SYMLINK_NAME) {
+		GnomeVFSResult result;
+
+		result = set_symlink_name_helper (full_name, info);
+		if (result != GNOME_VFS_OK) {
+			g_free (full_name);
+			return result;	
+		}
+	}
 
 	g_free (full_name);
 
Index: modules/sftp-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/sftp-method.c,v
retrieving revision 1.46
diff -u -p -r1.46 sftp-method.c
--- modules/sftp-method.c	13 Jul 2006 13:23:42 -0000	1.46
+++ modules/sftp-method.c	16 Jul 2006 05:57:12 -0000
@@ -3147,6 +3152,13 @@ do_set_file_info (GnomeVFSMethod        
 	gchar *path;
 
 	DEBUG (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s: Enter", G_GNUC_FUNCTION));
+
+	if ((mask & ~(GNOME_VFS_SET_FILE_INFO_NAME |
+		      GNOME_VFS_SET_FILE_INFO_PERMISSIONS |
+		      GNOME_VFS_SET_FILE_INFO_OWNER |
+		      GNOME_VFS_SET_FILE_INFO_TIME)) != 0) {
+		return GNOME_VFS_ERROR_NOT_SUPPORTED;
+	}
 
 	if (mask & (GNOME_VFS_SET_FILE_INFO_PERMISSIONS |
 		    GNOME_VFS_SET_FILE_INFO_OWNER |
