X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/53936ef935e97d2036ad09b61b7040979d175469..cc56eb2acca94ac29149d4a838fe43db6edc3867:/main.c diff --git a/main.c b/main.c index 8de7f1bd..5fba5e68 100644 --- a/main.c +++ b/main.c @@ -78,7 +78,7 @@ extern char *batch_name; extern char *password_file; extern char curr_dir[MAXPATHLEN]; extern struct file_list *first_flist; -extern struct filter_list_struct server_filter_list; +extern struct filter_list_struct daemon_filter_list; uid_t our_uid; int local_server = 0; @@ -341,7 +341,7 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in cmd = rsh_env; if (!cmd) cmd = RSYNC_RSH; - cmd = strdup(cmd); + cmd = strdup(cmd); /* MEMORY LEAK */ if (!cmd) goto oom; @@ -507,12 +507,28 @@ static char *get_local_name(struct file_list *flist, char *dest_path) if (!dest_path || list_only) return NULL; + if (daemon_filter_list.head) { + char *slash = strrchr(dest_path, '/'); + if (slash && slash[1] == '\0') + *slash = '\0'; + else + slash = NULL; + if (check_filter(&daemon_filter_list, FLOG, dest_path, 0) < 0 + || check_filter(&daemon_filter_list, FLOG, dest_path, 1) < 0) { + rprintf(FERROR, "skipping daemon-excluded destination \"%s\"\n", + dest_path); + exit_cleanup(RERR_FILESELECT); + } + if (slash) + *slash = '/'; + } + /* See what currently exists at the destination. */ if ((statret = do_stat(dest_path, &st)) == 0) { /* If the destination is a dir, enter it and use mode 1. */ if (S_ISDIR(st.st_mode)) { - if (!push_dir(dest_path, 0)) { - rsyserr(FERROR, errno, "push_dir#1 %s failed", + if (!change_dir(dest_path, CD_NORMAL)) { + rsyserr(FERROR, errno, "change_dir#1 %s failed", full_fname(dest_path)); exit_cleanup(RERR_FILESELECT); } @@ -571,8 +587,8 @@ static char *get_local_name(struct file_list *flist, char *dest_path) dry_run++; } - if (!push_dir(dest_path, dry_run > 1)) { - rsyserr(FERROR, errno, "push_dir#2 %s failed", + if (!change_dir(dest_path, dry_run > 1 ? CD_SKIP_CHDIR : CD_NORMAL)) { + rsyserr(FERROR, errno, "change_dir#2 %s failed", full_fname(dest_path)); exit_cleanup(RERR_FILESELECT); } @@ -591,8 +607,8 @@ static char *get_local_name(struct file_list *flist, char *dest_path) dest_path = "/"; *cp = '\0'; - if (!push_dir(dest_path, 0)) { - rsyserr(FERROR, errno, "push_dir#3 %s failed", + if (!change_dir(dest_path, CD_NORMAL)) { + rsyserr(FERROR, errno, "change_dir#3 %s failed", full_fname(dest_path)); exit_cleanup(RERR_FILESELECT); } @@ -684,8 +700,8 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[]) } if (!relative_paths) { - if (!push_dir(dir, 0)) { - rsyserr(FERROR, errno, "push_dir#3 %s failed", + if (!change_dir(dir, CD_NORMAL)) { + rsyserr(FERROR, errno, "change_dir#3 %s failed", full_fname(dir)); exit_cleanup(RERR_FILESELECT); } @@ -854,8 +870,8 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) char *dir = argv[0]; argc--; argv++; - if (!am_daemon && !push_dir(dir, 0)) { - rsyserr(FERROR, errno, "push_dir#4 %s failed", + if (!am_daemon && !change_dir(dir, CD_NORMAL)) { + rsyserr(FERROR, errno, "change_dir#4 %s failed", full_fname(dir)); exit_cleanup(RERR_FILESELECT); } @@ -894,25 +910,25 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) if (sanitize_paths) { char **dir_p; for (dir_p = basis_dir; *dir_p; dir_p++) - *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth); + *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth, SP_DEFAULT); if (partial_dir) - partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth); + partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth, SP_DEFAULT); } check_alt_basis_dirs(); - if (server_filter_list.head) { + if (daemon_filter_list.head) { char **dir_p; - struct filter_list_struct *elp = &server_filter_list; + struct filter_list_struct *elp = &daemon_filter_list; for (dir_p = basis_dir; *dir_p; dir_p++) { char *dir = *dir_p; if (*dir == '/') dir += module_dirlen; - if (check_filter(elp, dir, 1) < 0) + if (check_filter(elp, FLOG, dir, 1) < 0) goto options_rejected; } if (partial_dir && *partial_dir == '/' - && check_filter(elp, partial_dir + module_dirlen, 1) < 0) { + && check_filter(elp, FLOG, partial_dir + module_dirlen, 1) < 0) { options_rejected: rprintf(FERROR, "Your options have been rejected by the server.\n"); @@ -1030,11 +1046,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_start_multiplex_out(); } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } - send_filter_list(read_batch ? -1 : f_out); if (filesfrom_fd >= 0) { @@ -1145,8 +1156,6 @@ static int start_client(int argc, char *argv[]) static char *dotarg[1] = { "." }; p = dotarg[0]; remote_argv = dotarg; - list_only |= 1; - xfer_dirs |= 1; } remote_argc = 1; @@ -1218,10 +1227,6 @@ static int start_client(int argc, char *argv[]) } remote_argv[i] = arg; } - if (argc == 0) { - list_only |= 1; - xfer_dirs |= 1; - } } if (daemon_over_rsh < 0) @@ -1431,11 +1436,11 @@ int main(int argc,char *argv[]) SIGACTION(SIGXFSZ, SIG_IGN); #endif - /* Initialize push_dir here because on some old systems getcwd + /* Initialize change_dir() here because on some old systems getcwd * (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, 0); + change_dir(NULL, CD_NORMAL); init_flist(); @@ -1459,7 +1464,6 @@ int main(int argc,char *argv[]) read_stream_flags(batch_fd); else write_stream_flags(batch_fd); - } if (write_batch < 0) dry_run = 1;