X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/29bca53f9b6c020b5bd226b6378482a203fa7df3..62a6b8df72d18f0b13462ee7ac33f9a8a46ef0b5:/main.c diff --git a/main.c b/main.c index 304f8be2..ba470481 100644 --- a/main.c +++ b/main.c @@ -41,7 +41,7 @@ extern int remove_source_files; extern int need_messages_from_generator; extern int kluge_around_eof; extern int do_stats; -extern int log_got_error; +extern int got_xfer_error; extern int module_id; extern int copy_links; extern int copy_dirlinks; @@ -63,10 +63,13 @@ extern int read_batch; extern int write_batch; extern int batch_fd; extern int filesfrom_fd; +extern int connect_timeout; extern pid_t cleanup_child_pid; +extern unsigned int module_dirlen; extern struct stats stats; extern char *filesfrom_host; extern char *partial_dir; +extern char *dest_option; extern char *basis_dir[]; extern char *rsync_path; extern char *shell_cmd; @@ -330,7 +333,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in int i, argc = 0; char *args[MAX_ARGS]; pid_t ret; - char *dir = NULL; int dash_l_set = 0; if (!read_batch && !local_server) { @@ -506,9 +508,6 @@ static pid_t do_cmd(char *cmd, char *machine, char *user, char **remote_argv, in ret = piped_child(args, f_in_p, f_out_p); } - if (dir) - free(dir); - return ret; oom: @@ -637,36 +636,41 @@ 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) +/* This function checks on our alternate-basis directories. If we're in + * dry-run mode and the destination dir does not yet exist, we'll try to + * tweak any dest-relative paths to make them work for a dry-run (the + * destination dir must be in curr_dir[] when this function is called). + * We also report if any arg that is non-existent or not a directory. */ +static void check_alt_basis_dirs(void) { - char **dir, *new, *slash; - int len; - - if (dry_run <= 1) - return; - - slash = strrchr(curr_dir, '/'); - - 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"); - if (slash && strncmp(*dir, "../", 3) == 0) { - /* We want to remove only one leading "../" prefix for - * the directory we couldn't create in dry-run mode: - * this ensures that any other ".." references get - * evaluated the same as they would for a live copy. */ - *slash = '\0'; - pathjoin(new, len, curr_dir, *dir + 3); - *slash = '/'; - } else - pathjoin(new, len, curr_dir, *dir); - *dir = new; + STRUCT_STAT st; + char **dir_p, *slash = strrchr(curr_dir, '/'); + + for (dir_p = basis_dir; *dir_p; dir_p++) { + if (dry_run > 1 && **dir_p != '/') { + int len = curr_dir_len + 1 + strlen(*dir_p) + 1; + char *new = new_array(char, len); + if (!new) + out_of_memory("check_alt_basis_dirs"); + if (slash && strncmp(*dir_p, "../", 3) == 0) { + /* We want to remove only one leading "../" prefix for + * the directory we couldn't create in dry-run mode: + * this ensures that any other ".." references get + * evaluated the same as they would for a live copy. */ + *slash = '\0'; + pathjoin(new, len, curr_dir, *dir_p + 3); + *slash = '/'; + } else + pathjoin(new, len, curr_dir, *dir_p); + *dir_p = new; + } + if (do_stat(*dir_p, &st) < 0) { + rprintf(FWARNING, "%s arg does not exist: %s\n", + dest_option, *dir_p); + } else if (!S_ISDIR(st.st_mode)) { + rprintf(FWARNING, "%s arg is not a dir: %s\n", + dest_option, *dir_p); + } } } @@ -862,7 +866,6 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) int exit_code; struct file_list *flist; char *local_name = NULL; - char *dir = NULL; int save_verbose = verbose; if (filesfrom_fd >= 0) { @@ -883,7 +886,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) } if (argc > 0) { - dir = argv[0]; + char *dir = argv[0]; argc--; argv++; if (!am_daemon && !push_dir(dir, 0)) { @@ -924,26 +927,27 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) /* Now that we know what our destination directory turned out to be, * we can sanitize the --link-/copy-/compare-dest args correctly. */ if (sanitize_paths) { - char **dir; - for (dir = basis_dir; *dir; dir++) { - *dir = sanitize_path(NULL, *dir, NULL, curr_dir_depth); - } - if (partial_dir) { + char **dir_p; + for (dir_p = basis_dir; *dir_p; dir_p++) + *dir_p = sanitize_path(NULL, *dir_p, NULL, curr_dir_depth); + if (partial_dir) partial_dir = sanitize_path(NULL, partial_dir, NULL, curr_dir_depth); - } } - fix_basis_dirs(); + check_alt_basis_dirs(); if (server_filter_list.head) { - char **dir; + char **dir_p; struct filter_list_struct *elp = &server_filter_list; - for (dir = basis_dir; *dir; dir++) { - if (check_filter(elp, *dir, 1) < 0) + 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) goto options_rejected; } if (partial_dir && *partial_dir == '/' - && check_filter(elp, partial_dir, 1) < 0) { + && check_filter(elp, partial_dir + module_dirlen, 1) < 0) { options_rejected: rprintf(FERROR, "Your options have been rejected by the server.\n"); @@ -1082,7 +1086,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (flist && flist->used > 0) { local_name = get_local_name(flist, argv[0]); - fix_basis_dirs(); + check_alt_basis_dirs(); exit_code2 = do_recv(f_in, f_out, local_name); } else { @@ -1264,6 +1268,12 @@ static int start_client(int argc, char *argv[]) exit_cleanup(RERR_SYNTAX); } + if (connect_timeout) { + rprintf(FERROR, "The --contimeout option may only be " + "used when connecting to an rsync daemon.\n"); + exit_cleanup(RERR_SYNTAX); + } + if (shell_machine) { p = strrchr(shell_machine,'@'); if (p) { @@ -1310,7 +1320,7 @@ static RETSIGTYPE sigusr2_handler(UNUSED(int val)) if (!am_server) output_summary(); close_all(); - if (log_got_error) + if (got_xfer_error) _exit(RERR_PARTIAL); _exit(0); }