--- openssh-3.8.1p1/sftp-server.c	Mon Feb 23 17:19:15 2004
+++ openssh-3.8.1p1-tmpfile/sftp-server.c	Sat Jun  5 15:09:58 2004
@@ -30,6 +30,7 @@
 #define get_int()			buffer_get_int(&iqueue);
 #define get_string(lenp)		buffer_get_string(&iqueue, lenp);
 #define TRACE				debug
+#define TMPNAME_SUFFIX	".sftp_tmp"
 
 #ifdef HAVE___PROGNAME
 extern char *__progname;
@@ -121,6 +122,7 @@
 	DIR *dirp;
 	int fd;
 	char *name;
+	char *tmpname;
 };
 
 enum {
@@ -141,7 +143,7 @@
 }
 
 static int
-handle_new(int use, const char *name, int fd, DIR *dirp)
+handle_new(int use, const char *name, char *tmpname, int fd, DIR *dirp)
 {
 	int i;
 
@@ -151,6 +153,7 @@
 			handles[i].dirp = dirp;
 			handles[i].fd = fd;
 			handles[i].name = xstrdup(name);
+			if (tmpname) handles[i].tmpname = xstrdup(tmpname);
 			return i;
 		}
 	}
@@ -221,6 +224,10 @@
 
 	if (handle_is_ok(handle, HANDLE_FILE)) {
 		ret = close(handles[handle].fd);
+		if (handles[handle].tmpname) {
+			rename(handles[handle].tmpname,handles[handle].name);
+			xfree(handles[handle].tmpname);
+		}
 		handles[handle].use = HANDLE_UNUSED;
 		xfree(handles[handle].name);
 	} else if (handle_is_ok(handle, HANDLE_DIR)) {
@@ -376,21 +383,31 @@
 {
 	u_int32_t id, pflags;
 	Attrib *a;
-	char *name;
-	int handle, fd, flags, mode, status = SSH2_FX_FAILURE;
+	char *name,*tmpname=NULL;
+	int handle, tmpnamelen, fd, flags, mode, status = SSH2_FX_FAILURE;
 
 	id = get_int();
 	name = get_string(NULL);
 	pflags = get_int();		/* portable flags */
+	if (pflags & (SSH2_FXF_WRITE|SSH2_FXF_CREAT|SSH2_FXF_TRUNC)) {
+		tmpnamelen=strlen(name)+strlen(TMPNAME_SUFFIX)+1;
+		tmpname=xmalloc(tmpnamelen);
+		strlcpy(tmpname,name,tmpnamelen);
+		strlcat(tmpname,TMPNAME_SUFFIX,tmpnamelen);
+	}
 	a = get_attrib();
 	flags = flags_from_portable(pflags);
 	mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666;
 	TRACE("open id %u name %s flags %d mode 0%o", id, name, pflags, mode);
-	fd = open(name, flags, mode);
+	if (tmpname) {
+		fd = open(tmpname, flags, mode);
+	} else {
+		fd = open(name, flags, mode);
+	}
 	if (fd < 0) {
 		status = errno_to_portable(errno);
 	} else {
-		handle = handle_new(HANDLE_FILE, name, fd, NULL);
+		handle = handle_new(HANDLE_FILE, name,tmpname, fd, NULL);
 		if (handle < 0) {
 			close(fd);
 		} else {
@@ -675,7 +692,7 @@
 	if (dirp == NULL) {
 		status = errno_to_portable(errno);
 	} else {
-		handle = handle_new(HANDLE_DIR, path, 0, dirp);
+		handle = handle_new(HANDLE_DIR, path,NULL, 0, dirp);
 		if (handle < 0) {
 			closedir(dirp);
 		} else {
