X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/9ae7a2cddbb19d14e1b4453cfd40d840ea3042d2..9b49704959f4b7ecb482f3d1f87ba2735e1d7ed1:/main.c diff --git a/main.c b/main.c index 273513fe..e9675f96 100644 --- a/main.c +++ b/main.c @@ -4,11 +4,11 @@ * Copyright (C) 1996-2001 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool - * Copyright (C) 2003, 2004, 2005, 2006 Wayne Davison + * Copyright (C) 2003-2007 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, @@ -17,11 +17,11 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + * with this program; if not, visit the http://fsf.org website. */ #include "rsync.h" +#include "io.h" #if defined CONFIG_LOCALE && defined HAVE_LOCALE_H #include #endif @@ -34,10 +34,9 @@ extern int am_server; extern int am_sender; extern int am_generator; extern int am_daemon; -extern int incremental; +extern int inc_recurse; extern int blocking_io; extern int remove_source_files; -extern int daemon_over_rsh; extern int need_messages_from_generator; extern int kluge_around_eof; extern int do_stats; @@ -71,10 +70,12 @@ extern char *shell_cmd; extern char *batch_name; extern char *password_file; extern char curr_dir[MAXPATHLEN]; +extern struct file_list *cur_flist; extern struct filter_list_struct server_filter_list; int local_server = 0; int new_root_dir = 0; +int daemon_over_rsh = 0; mode_t orig_umask = 0; int batch_gen_fd = -1; @@ -191,12 +192,12 @@ static void handle_stats(int f) if (am_server) { if (am_sender) { - write_longint(f, total_read); - write_longint(f, total_written); - write_longint(f, stats.total_size); + write_varlong30(f, total_read, 3); + write_varlong30(f, total_written, 3); + write_varlong30(f, stats.total_size, 3); if (protocol_version >= 29) { - write_longint(f, stats.flist_buildtime); - write_longint(f, stats.flist_xfertime); + write_varlong30(f, stats.flist_buildtime, 3); + write_varlong30(f, stats.flist_xfertime, 3); } } return; @@ -209,22 +210,22 @@ static void handle_stats(int f) else if (!am_sender) { /* Read the first two in opposite order because the meaning of * read/write swaps when switching from sender to receiver. */ - total_written = read_longint(f); - total_read = read_longint(f); - stats.total_size = read_longint(f); + total_written = read_varlong30(f, 3); + total_read = read_varlong30(f, 3); + stats.total_size = read_varlong30(f, 3); if (protocol_version >= 29) { - stats.flist_buildtime = read_longint(f); - stats.flist_xfertime = read_longint(f); + stats.flist_buildtime = read_varlong30(f, 3); + stats.flist_xfertime = read_varlong30(f, 3); } } else if (write_batch) { /* The --read-batch process is going to be a client * receiver, so we need to give it the stats. */ - write_longint(batch_fd, total_read); - write_longint(batch_fd, total_written); - write_longint(batch_fd, stats.total_size); + write_varlong30(batch_fd, total_read, 3); + write_varlong30(batch_fd, total_written, 3); + write_varlong30(batch_fd, stats.total_size, 3); if (protocol_version >= 29) { - write_longint(batch_fd, stats.flist_buildtime); - write_longint(batch_fd, stats.flist_xfertime); + write_varlong30(batch_fd, stats.flist_buildtime, 3); + write_varlong30(batch_fd, stats.flist_xfertime, 3); } } } @@ -609,7 +610,7 @@ static void fix_basis_dirs(void) } /* This is only called by the sender. */ -static void read_final_goodbye(int f_in, int f_out) +static void read_final_goodbye(int f_in) { int i, iflags, xlen; uchar fnamecmp_type; @@ -618,8 +619,8 @@ static void read_final_goodbye(int f_in, int f_out) if (protocol_version < 29) i = read_int(f_in); else { - i = read_ndx_and_attrs(f_in, f_out, &iflags, - &fnamecmp_type, xname, &xlen); + i = read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, + xname, &xlen); } if (i != NDX_DONE) { @@ -669,7 +670,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[]) } flist = send_file_list(f_out,argc,argv); - if (!flist || flist->count == 0) + if (!flist || flist->used == 0) exit_cleanup(0); io_start_buffering_in(f_in); @@ -678,7 +679,7 @@ static void do_server_sender(int f_in, int f_out, int argc, char *argv[]) io_flush(FULL_FLUSH); handle_stats(f_out); if (protocol_version >= 24) - read_final_goodbye(f_in, f_out); + read_final_goodbye(f_in); io_flush(FULL_FLUSH); exit_cleanup(0); } @@ -695,8 +696,8 @@ static int do_recv(int f_in, int f_out, char *local_name) copy_links = copy_dirlinks = 0; #ifdef SUPPORT_HARD_LINKS - if (preserve_hard_links) - match_hard_links(); + if (preserve_hard_links && !inc_recurse) + match_hard_links(cur_flist); #endif if (fd_pair(error_pipe) < 0) { @@ -727,7 +728,8 @@ static int do_recv(int f_in, int f_out, char *local_name) io_flush(FULL_FLUSH); handle_stats(f_in); - send_msg(MSG_DONE, "", 0); + send_msg(MSG_DONE, "", 1, 0); + write_varlong(error_pipe[1], stats.total_read, 3); io_flush(FULL_FLUSH); /* Handle any keep-alive packets from the post-processing work @@ -740,7 +742,7 @@ static int do_recv(int f_in, int f_out, char *local_name) kluge_around_eof = -1; /* This should only get stopped via a USR2 signal. */ - read_ndx_and_attrs(f_in, -1, &iflags, &fnamecmp_type, + read_ndx_and_attrs(f_in, &iflags, &fnamecmp_type, xname, &xlen); rprintf(FERROR, "Invalid packet at end of run [%s]\n", @@ -843,7 +845,7 @@ static void do_server_recv(int f_in, int f_out, int argc, char *argv[]) rprintf(FERROR,"server_recv: recv_file_list error\n"); exit_cleanup(RERR_FILESELECT); } - if (incremental && file_total == 1) + if (inc_recurse && file_total == 1) recv_additional_file_list(f_in); verbose = save_verbose; @@ -899,7 +901,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[]) io_set_sock_fds(f_in, f_out); setup_protocol(f_out, f_in); -#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H +#ifdef ICONV_CONST setup_iconv(); #endif @@ -936,7 +938,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_set_sock_fds(f_in, f_out); setup_protocol(f_out,f_in); -#if defined HAVE_ICONV_OPEN && defined HAVE_ICONV_H +#ifdef ICONV_CONST setup_iconv(); #endif @@ -977,7 +979,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) io_flush(FULL_FLUSH); handle_stats(-1); if (protocol_version >= 24) - read_final_goodbye(f_in, f_out); + read_final_goodbye(f_in); if (pid != -1) { if (verbose > 3) rprintf(FINFO,"client_run waiting on %d\n", (int) pid); @@ -1009,10 +1011,10 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[]) if (write_batch && !am_server) start_write_batch(f_in); flist = recv_file_list(f_in); - if (incremental && file_total == 1) + if (inc_recurse && file_total == 1) recv_additional_file_list(f_in); - if (flist && flist->count > 0) { + if (flist && flist->used > 0) { local_name = get_local_name(flist, argv[0]); fix_basis_dirs(); @@ -1091,16 +1093,9 @@ static int start_client(int argc, char *argv[]) "--files-from hostname is not the same as the transfer hostname\n"); exit_cleanup(RERR_SYNTAX); } - if (rsync_port) { - if (!shell_cmd) { - return start_socket_client(shell_machine, - shell_path, - argc, argv); - } - daemon_over_rsh = 1; - } - am_sender = 0; + if (rsync_port) + daemon_over_rsh = shell_cmd ? 1 : -1; } else { /* source is local, check dest arg */ am_sender = 1; @@ -1127,14 +1122,8 @@ static int start_client(int argc, char *argv[]) } shell_machine = NULL; shell_path = p; - } else if (rsync_port) { - if (!shell_cmd) { - return start_socket_client(shell_machine, - shell_path, - argc, argv); - } - daemon_over_rsh = 1; - } + } else if (rsync_port) + daemon_over_rsh = shell_cmd ? 1 : -1; } } else { /* read_batch */ local_server = 1; @@ -1145,6 +1134,15 @@ static int start_client(int argc, char *argv[]) } } + /* for remote source, only single dest arg can remain ... */ + if (!am_sender && argc > 1) { + usage(FERROR); + exit_cleanup(RERR_SYNTAX); + } + + if (daemon_over_rsh < 0) + return start_socket_client(shell_machine, shell_path, argc, argv); + if (password_file && !daemon_over_rsh) { rprintf(FERROR, "The --password-file option may only be " "used when accessing an rsync daemon.\n"); @@ -1168,12 +1166,6 @@ static int start_client(int argc, char *argv[]) shell_path ? shell_path : ""); } - /* for remote source, only single dest arg can remain ... */ - if (!am_sender && argc > 1) { - usage(FERROR); - exit_cleanup(RERR_SYNTAX); - } - /* ... or no dest at all */ if (!am_sender && argc == 0) list_only |= 1;