diff -urd vsftpd-1.2.2.orig/Changelog vsftpd-1.2.2/Changelog
--- vsftpd-1.2.2.orig/Changelog	2004-04-26 21:05:23.000000000 +0300
+++ vsftpd-1.2.2/Changelog	2004-05-12 22:19:23.950739376 +0300
@@ -766,3 +766,4 @@
 At this point: v1.2.2 released! (need to get the listener fix out)
 ==================================================================
 
+- upload temporary dot prefixed file and rename it when uploaded
diff -urd vsftpd-1.2.2.orig/postlogin.c vsftpd-1.2.2/postlogin.c
--- vsftpd-1.2.2.orig/postlogin.c	2004-04-21 02:31:05.000000000 +0300
+++ vsftpd-1.2.2/postlogin.c	2004-05-12 22:29:09.570711608 +0300
@@ -62,6 +62,7 @@
 static void handle_dir_common(struct vsf_session* p_sess, int full_details,
                               int stat_cmd);
 static void prepend_path_to_filename(struct mystr* p_str);
+static void add_dot_to_filename(struct mystr* p_str);
 static int get_remote_transfer_fd(struct vsf_session* p_sess);
 static int dispose_remote_transfer_fd(struct vsf_session* p_sess);
 static void handle_sigurg(void* p_private);
@@ -935,9 +936,11 @@
   struct mystr* p_filename;
   struct vsf_transfer_ret trans_ret;
   int new_file_fd;
+  int real_file_fd;
   int remote_fd;
   int retval;
   filesize_t offset = p_sess->restart_pos;
+  static struct mystr s_tmp_str;
   p_sess->restart_pos = 0;
   if (!pasv_active(p_sess) && !port_active(p_sess))
   {
@@ -961,7 +964,25 @@
    */
   if (is_unique || (p_sess->is_anonymous && !tunable_anon_other_write_enable))
   {
-    new_file_fd = str_create(p_filename);
+    /* Create empty file to hold it used */
+    real_file_fd = str_create(p_filename);
+    if (vsf_sysutil_retval_is_error(real_file_fd))
+    {
+      vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create file.");
+      return;
+    }
+    vsf_sysutil_close(real_file_fd);
+    /* create temporary file with prefix '.' */
+    str_copy(&s_tmp_str, p_filename);
+    add_dot_to_filename(&s_tmp_str);
+    new_file_fd = str_create(&s_tmp_str);
+    if (vsf_sysutil_retval_is_error(new_file_fd))
+    {
+      str_unlink(p_filename);
+      str_unlink(&s_tmp_str);
+      vsf_cmdio_write(p_sess, FTP_UPLOADFAIL, "Could not create temporary file.");
+      return;
+    }
   }
   else
   {
@@ -1030,6 +1051,14 @@
   }
   p_sess->transfer_size = trans_ret.transferred;
   /* XXX - handle failure, delete file? */
+
+  if (p_sess->is_anonymous && !tunable_anon_other_write_enable)
+  {
+    retval = str_rename(&s_tmp_str, &p_sess->ftp_arg_str);
+    if (retval != 0)
+      vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Temporary file rename failed.");
+  }
+
   retval = dispose_remote_transfer_fd(p_sess);
   /* Log _after_ the blocking dispose call, so we get transfer times right */
   if (trans_ret.retval == 0 && retval == 0)
@@ -1229,6 +1258,33 @@
 
 
 static void
+add_dot_to_filename(struct mystr* p_str)
+{
+  struct str_locate_result loc_result;
+  static struct mystr s_tmp_str;
+  static struct mystr s_filename_str;
+
+  loc_result = str_locate_char(p_str, '/');
+  if (loc_result.found)
+  {
+    /* filename with path */
+    str_empty(&s_tmp_str);
+    str_split_char_reverse(p_str, &s_filename_str, '/');
+    str_append_text(p_str, "/.");
+    str_append_str(p_str, &s_filename_str);
+    return;
+  } else {
+    /* filename without path */
+    str_empty(&s_tmp_str);
+    str_alloc_text(&s_tmp_str, ".");
+    str_append_str(&s_tmp_str, p_str);
+    str_copy(p_str, &s_tmp_str);
+    return;
+  }
+}
+
+
+static void
 handle_sigurg(void* p_private)
 {
   struct mystr async_cmd_str = INIT_MYSTR;
diff -urd vsftpd-1.2.2.orig/str.c vsftpd-1.2.2/str.c
--- vsftpd-1.2.2.orig/str.c	2003-09-20 03:46:39.000000000 +0300
+++ vsftpd-1.2.2/str.c	2004-05-12 22:19:23.960737856 +0300
@@ -476,6 +476,15 @@
 }
 
 struct str_locate_result
+str_locate_char_reverse(const struct mystr* p_str, char look_char)
+{
+  char look_str[2];
+  look_str[0] = look_char;
+  look_str[1] = '\0';
+  return str_locate_text_reverse(p_str, look_str);
+}
+
+struct str_locate_result
 str_locate_text_reverse(const struct mystr* p_str, const char* p_text)
 {
   struct str_locate_result retval;
diff -urd vsftpd-1.2.2.orig/str.h vsftpd-1.2.2/str.h
--- vsftpd-1.2.2.orig/str.h	2003-07-31 00:20:05.000000000 +0300
+++ vsftpd-1.2.2/str.h	2004-05-12 22:19:23.962737552 +0300
@@ -76,6 +76,8 @@
   const struct mystr* p_str, char look_char);
 struct str_locate_result str_locate_str(
   const struct mystr* p_str, const struct mystr* p_look_str);
+struct str_locate_result str_locate_char_reverse(
+  const struct mystr* p_str, char look_char);
 struct str_locate_result str_locate_str_reverse(
   const struct mystr* p_str, const struct mystr* p_look_str);
 struct str_locate_result str_locate_text(
