aboutsummaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2006-10-08 20:56:56 +0000
committerWayne Davison <wayned@samba.org>2006-10-08 20:56:56 +0000
commit615a5415c9f3b156f3f456688f8b702fa05deb8d (patch)
treed54cd595973c0ef7cd6aea26490c8f4425f5a0a5 /main.c
parentba081be327dac7fe6018ee4f14e9b07ace99ac73 (diff)
downloadandroid_external_rsync-615a5415c9f3b156f3f456688f8b702fa05deb8d.tar.gz
android_external_rsync-615a5415c9f3b156f3f456688f8b702fa05deb8d.tar.bz2
android_external_rsync-615a5415c9f3b156f3f456688f8b702fa05deb8d.zip
- Call push_dir() with its new boolean arg, including the spot in
get_local_name() where we need push_dir() to skip the chdir() because the destination dir does no yet exist and --dry-run was specified. - Added fix_basis_dirs(), which will combine the dest-dir with each non- absolute basis_dir arg to make sure that they end up being relative to the right dir when --dry-run was specified and the dest dir does not yet exist.
Diffstat (limited to 'main.c')
-rw-r--r--main.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/main.c b/main.c
index c37b3c79..ed0ce0ad 100644
--- a/main.c
+++ b/main.c
@@ -51,6 +51,7 @@ extern int recurse;
extern int relative_paths;
extern int sanitize_paths;
extern int curr_dir_depth;
+extern int curr_dir_len;
extern int module_id;
extern int rsync_port;
extern int whole_file;
@@ -67,6 +68,7 @@ extern char *basis_dir[];
extern char *rsync_path;
extern char *shell_cmd;
extern char *batch_name;
+extern char curr_dir[MAXPATHLEN];
extern struct filter_list_struct server_filter_list;
int local_server = 0;
@@ -479,7 +481,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
if (S_ISDIR(st.st_mode)) {
if (sanitize_paths)
die_on_unsafe_path(dest_path, 0);
- if (!push_dir(dest_path)) {
+ if (!push_dir(dest_path, 0)) {
rsyserr(FERROR, errno, "push_dir#1 %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
@@ -534,15 +536,13 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
rprintf(FINFO, "created directory %s\n", dest_path);
if (dry_run) {
- /* Indicate that the destination directory doesn't
- * really exist and return mode 1. */
+ /* Indicate that dest dir doesn't really exist. */
dry_run++;
- return NULL;
}
if (sanitize_paths)
die_on_unsafe_path(dest_path, 0);
- if (!push_dir(dest_path)) {
+ if (!push_dir(dest_path, dry_run > 1)) {
rsyserr(FERROR, errno, "push_dir#2 %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
@@ -564,7 +564,7 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
*cp = '\0';
if (sanitize_paths)
die_on_unsafe_path(dest_path, 0);
- if (!push_dir(dest_path)) {
+ if (!push_dir(dest_path, 0)) {
rsyserr(FERROR, errno, "push_dir#3 %s failed",
full_fname(dest_path));
exit_cleanup(RERR_FILESELECT);
@@ -574,6 +574,25 @@ static char *get_local_name(struct file_list *flist, char *dest_path)
return cp + 1;
}
+/* Call this if the destination dir (which is assumed to be in curr_dir)
+ * does not yet exist and we can't create it due to being in dry-run
+ * mode. We'll fix dirs that can be relative to the non-existent dir. */
+static void fix_basis_dirs(void)
+{
+ char **dir, *new;
+ int len;
+
+ for (dir = basis_dir; *dir; dir++) {
+ if (**dir == '/')
+ continue;
+ len = curr_dir_len + 1 + strlen(*dir) + 1;
+ if (!(new = new_array(char, len)))
+ out_of_memory("fix_basis_dirs");
+ pathjoin(new, len, curr_dir, *dir);
+ clean_fname(new, 1);
+ *dir = new;
+ }
+}
/* This is only called by the sender. */
static void read_final_goodbye(int f_in, int f_out)
@@ -625,7 +644,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[])
if (!relative_paths) {
if (sanitize_paths)
die_on_unsafe_path(dir, 0);
- if (!push_dir(dir)) {
+ if (!push_dir(dir, 0)) {
rsyserr(FERROR, errno, "push_dir#3 %s failed",
full_fname(dir));
exit_cleanup(RERR_FILESELECT);
@@ -782,7 +801,7 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
dir = argv[0];
argc--;
argv++;
- if (!am_daemon && !push_dir(dir)) {
+ if (!am_daemon && !push_dir(dir, 0)) {
rsyserr(FERROR, errno, "push_dir#4 %s failed",
full_fname(dir));
exit_cleanup(RERR_FILESELECT);
@@ -828,6 +847,9 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
die_on_unsafe_path(partial_dir, 0);
}
}
+ if (dry_run > 1)
+ fix_basis_dirs();
+
if (server_filter_list.head) {
char **dir;
struct filter_list_struct *elp = &server_filter_list;
@@ -975,6 +997,9 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (flist && flist->count > 0) {
local_name = get_local_name(flist, argv[0]);
+ if (dry_run > 1)
+ fix_basis_dirs();
+
exit_code2 = do_recv(f_in, f_out, flist, local_name);
} else {
handle_stats(-1);
@@ -1311,7 +1336,7 @@ int main(int argc,char *argv[])
* (implemented by forking "pwd" and reading its output) doesn't
* work when there are other child processes. Also, on all systems
* that implement getcwd that way "pwd" can't be found after chroot. */
- push_dir(NULL);
+ push_dir(NULL, 0);
init_flist();