X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/9eeb3b9c88d62bac0fed650fdbc310d5958cc541..ab759cd27becb80df39eb1a90e88c74cd7e9be77:/main.c diff --git a/main.c b/main.c index 0c355362..008f2164 100644 --- a/main.c +++ b/main.c @@ -43,6 +43,7 @@ extern int local_server; extern int log_got_error; extern int module_id; extern int orig_umask; +extern int copy_links; extern int keep_dirlinks; extern int preserve_hard_links; extern int protocol_version; @@ -177,15 +178,15 @@ static void report(int f) rprintf(FINFO,"Matched data: %.0f bytes\n", (double)stats.matched_data); rprintf(FINFO,"File list size: %d\n", stats.flist_size); - rprintf(FINFO,"Total bytes written: %.0f\n", + rprintf(FINFO,"Total bytes sent: %.0f\n", (double)total_written); - rprintf(FINFO,"Total bytes read: %.0f\n", + rprintf(FINFO,"Total bytes received: %.0f\n", (double)total_read); } if (verbose || do_stats) { rprintf(FINFO, - "\nwrote %.0f bytes read %.0f bytes %.2f bytes/sec\n", + "\nsent %.0f bytes received %.0f bytes %.2f bytes/sec\n", (double)total_written, (double)total_read, (total_written + total_read)/(0.5 + (t - starttime))); rprintf(FINFO, "total size is %.0f speedup is %.2f\n", @@ -378,9 +379,13 @@ static char *get_local_name(struct file_list *flist,char *name) if (do_mkdir(name,0777 & ~orig_umask) != 0) { rsyserr(FERROR, errno, "mkdir %s failed", full_fname(name)); exit_cleanup(RERR_FILEIO); - } else { - if (verbose > 0) - rprintf(FINFO,"created directory %s\n",name); + } + if (verbose > 0) + rprintf(FINFO, "created directory %s\n", name); + + if (dry_run) { + dry_run++; + return NULL; } if (!push_dir(name)) { @@ -458,6 +463,10 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) int status = 0; int error_pipe[2]; + /* The receiving side mustn't obey this, or an existing symlink that + * points to an identical file won't be replaced by the referent. */ + copy_links = 0; + if (preserve_hard_links) init_hard_links(flist); @@ -468,7 +477,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name) } if (fd_pair(error_pipe) < 0) { - rprintf(FERROR,"error pipe failed in do_recv\n"); + rsyserr(FERROR, errno, "pipe failed in do_recv"); exit_cleanup(RERR_SOCKETIO); } @@ -648,6 +657,16 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (protocol_version >= 23 && !read_batch) io_start_multiplex_in(); + /* We set our stderr file handle to blocking because ssh might have + * set it to non-blocking. This can be particularly troublesome if + * stderr is a clone of stdout, because ssh would have set our stdout + * to non-blocking at the same time (which can easily cause us to lose + * output from our print statements). This kluge shouldn't cause ssh + * any problems for how we use it. Note also that we delayed setting + * this until after the above protocol setup so that we know for sure + * that ssh is done twiddling its file descriptors. */ + set_blocking(STDERR_FILENO); + if (am_sender) { keep_dirlinks = 0; /* Must be disabled on the sender. */ io_start_buffering_out(); @@ -766,15 +785,20 @@ static int start_client(int argc, char *argv[]) host = argv[0] + strlen(URL_PREFIX); p = strchr(host,'/'); if (p) { - *p = 0; + *p = '\0'; path = p+1; - } else { + } else path = ""; - } - p = strchr(host,':'); + if (*host == '[' && (p = strchr(host, ']')) != NULL) { + host++; + *p++ = '\0'; + if (*p != ':') + p = NULL; + } else + p = strchr(host, ':'); if (p) { rsync_port = atoi(p+1); - *p = 0; + *p = '\0'; } return start_socket_client(host, path, argc-1, argv+1); } @@ -786,7 +810,7 @@ static int start_client(int argc, char *argv[]) && remote_filesfrom_file != files_from + 1 && strncmp(files_from, argv[0], p-argv[0]+1) != 0) { rprintf(FERROR, - "--files-from hostname is not transfer hostname\n"); + "--files-from hostname is not the same as the transfer hostname\n"); exit_cleanup(RERR_SYNTAX); } if (p[1] == ':') { /* double colon */ @@ -819,15 +843,20 @@ static int start_client(int argc, char *argv[]) host = argv[argc-1] + strlen(URL_PREFIX); p = strchr(host,'/'); if (p) { - *p = 0; + *p = '\0'; path = p+1; - } else { + } else path = ""; - } - p = strchr(host,':'); + if (*host == '[' && (p = strchr(host, ']')) != NULL) { + host++; + *p++ = '\0'; + if (*p != ':') + p = NULL; + } else + p = strchr(host, ':'); if (p) { rsync_port = atoi(p+1); - *p = 0; + *p = '\0'; } return start_socket_client(host, path, argc-1, argv); } @@ -837,14 +866,14 @@ static int start_client(int argc, char *argv[]) && remote_filesfrom_file != files_from + 1 && strncmp(files_from, argv[argc-1], p-argv[argc-1]+1) != 0) { rprintf(FERROR, - "--files-from hostname is not transfer hostname\n"); + "--files-from hostname is not the same as the transfer hostname\n"); exit_cleanup(RERR_SYNTAX); } if (!p) { /* no colon found, so src & dest are local */ local_server = 1; if (remote_filesfrom_file) { rprintf(FERROR, - "--files-from is remote but transfer is local\n"); + "--files-from cannot be remote when the transfer is local\n"); exit_cleanup(RERR_SYNTAX); } } else if (p[1] == ':') { /* double colon */