/**
* Close all open sockets and files, allowing a (somewhat) graceful
-@@ -113,6 +114,8 @@ void _exit_cleanup(int code, const char
+@@ -111,7 +112,8 @@ void _exit_cleanup(int code, const char
+ }
+ }
- if (cleanup_got_literal && cleanup_fname && keep_partial) {
+- if (cleanup_got_literal && cleanup_fname && keep_partial) {
++ if (cleanup_got_literal && cleanup_fname && keep_partial
++ && (!partial_dir || handle_partial_dir(cleanup_new_fname, 1))) {
char *fname = cleanup_fname;
-+ if (partial_dir)
-+ handle_partial_dir(cleanup_new_fname, 1);
cleanup_fname = NULL;
if (cleanup_fd_r != -1)
- close(cleanup_fd_r);
--- orig/generator.c 2004-07-23 17:16:12
+++ generator.c 2004-07-23 19:19:47
@@ -42,6 +42,7 @@ extern int size_only;
cleanup_disable();
if (!recv_ok) {
---- orig/rsync.yo 2004-07-23 17:16:13
+--- orig/rsync.yo 2004-07-24 16:52:10
+++ rsync.yo 2004-07-23 19:36:41
@@ -317,6 +317,7 @@ verb(
--ignore-errors delete even if there are I/O errors
dit(bf(--progress)) This option tells rsync to print information
showing the progress of the transfer. This gives a bored user
something to watch.
+--- orig/t_stub.c 2004-05-15 20:10:13
++++ t_stub.c 2004-07-24 17:00:35
+@@ -28,6 +28,7 @@
+
+ int modify_window = 0;
+ int module_id = -1;
++char *partial_dir;
+ struct exclude_list_struct server_exclude_list;
+
+ void rprintf(UNUSED(enum logcode code), const char *format, ...)
--- orig/util.c 2004-06-09 21:54:47
+++ util.c 2004-07-23 21:43:44
@@ -31,6 +31,7 @@ extern int verbose;
extern struct exclude_list_struct server_exclude_list;
int sanitize_paths = 0;
-@@ -945,6 +946,51 @@ char *full_fname(const char *fn)
+@@ -945,6 +946,74 @@ char *full_fname(const char *fn)
return result;
}
-+static char partialbuf[MAXPATHLEN];
++static char partial_fname[MAXPATHLEN];
+
+char *fname_in_partial_dir(const char *fname)
+{
-+ char *t = partialbuf;
-+ int sz = sizeof partialbuf;
++ char *t = partial_fname;
++ int sz = sizeof partial_fname;
+ const char *fn;
+
+ if ((fn = strrchr(fname, '/')) != NULL) {
+ } else
+ fn = fname;
+ if ((int)pathjoin(t, sz, partial_dir, fn) >= sz) {
-+ *partialbuf = '\0';
++ *partial_fname = '\0';
+ return NULL;
+ }
+
-+ return partialbuf;
++ return partial_fname;
+}
+
-+void handle_partial_dir(const char *fname, int create)
++int handle_partial_dir(const char *fname, int create)
+{
-+ char *fn;
++ char *fn, *dir = partial_fname;
+
-+ if (fname != partialbuf)
-+ return;
++ if (fname != partial_fname)
++ return 1;
+ if (!create && *partial_dir == '/')
-+ return;
-+ if (!(fn = strrchr(partialbuf, '/')))
-+ return;
++ return 1;
++ if (!(fn = strrchr(partial_fname, '/')))
++ return 1;
+
+ *fn = '\0';
-+ if (create)
-+ do_mkdir(partialbuf, 0700);
-+ else
-+ do_rmdir(partialbuf);
++ if (create) {
++ STRUCT_STAT st;
++#if SUPPORT_LINKS
++ int statret = do_lstat(dir, &st);
++#else
++ int statret = do_stat(dir, &st);
++#endif
++ if (statret == 0 && !S_ISDIR(st.st_mode)) {
++ if (do_unlink(dir) < 0)
++ return 0;
++ statret = -1;
++ }
++ if (statret < 0) {
++ if (do_mkdir(dir, 0700) < 0)
++ return 0;
++#if SUPPORT_LINKS
++ statret = do_lstat(dir, &st);
++#else
++ statret = do_stat(dir, &st);
++#endif
++ if (statret < 0 || !S_ISDIR(st.st_mode))
++ return 0;
++ }
++ } else
++ do_rmdir(dir);
+ *fn = '/';
++
++ return 1;
+}
+
/** We need to supply our own strcmp function for file list comparisons