Give the user an idea of how far along in the transfer we are
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index 29ee6ad..1b07eee 100644 (file)
--- a/main.c
+++ b/main.c
@@ -31,6 +31,7 @@ extern int am_server;
 extern int am_sender;
 extern int am_daemon;
 extern int verbose;
+extern int protocol_version;
 
 /* there's probably never more than at most 2 outstanding child processes,
  * but set it higher just in case.
@@ -82,7 +83,6 @@ static void report(int f)
 {
        time_t t = time(NULL);
        extern int do_stats;
-       extern int remote_version;
        int send_stats;
 
        if (do_stats && verbose > 1) {
@@ -96,7 +96,7 @@ static void report(int f)
                if (f == -1 || !am_sender) return;
        }
 
-       send_stats = verbose || (remote_version >= 20);
+       send_stats = verbose || protocol_version >= 20;
        if (am_server) {
                if (am_sender && send_stats) {
                        int64 w;
@@ -171,7 +171,7 @@ static void show_malloc_stats(void)
 
        mi = mallinfo();
 
-       rprintf(FINFO, RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
+       rprintf(FINFO, "\n" RSYNC_NAME "[%d] (%s%s%s) heap statistics:\n",
                getpid(),
                am_server ? "server " : "",
                am_daemon ? "daemon " : "",
@@ -205,8 +205,9 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
        extern int read_batch;
 
        if (!read_batch && !local_server) {
+               char *rsh_env = getenv(RSYNC_RSH_ENV);
                if (!cmd)
-                       cmd = getenv(RSYNC_RSH_ENV);
+                       cmd = rsh_env;
                if (!cmd)
                        cmd = RSYNC_RSH;
                cmd = strdup(cmd);
@@ -218,7 +219,7 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
                }
 
                /* check to see if we've already been given '-l user' in
-                  the remote-shell command */
+                * the remote-shell command */
                for (i = 0; i < argc-1; i++) {
                        if (!strcmp(args[i], "-l") && args[i+1][0] != '-')
                                dash_l_set = 1;
@@ -241,11 +242,17 @@ static pid_t do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int
 
                args[argc++] = rsync_path;
 
-               if ((blocking_io == -1) && (strcmp(cmd, RSYNC_RSH) == 0))
-                       blocking_io = 1;
+               if (blocking_io < 0) {
+                       char *cp;
+                       if ((cp = strrchr(cmd, '/')) != NULL)
+                               cp++;
+                       else
+                               cp = cmd;
+                       if (strcmp(cp, "rsh") == 0 || strcmp(cp, "remsh") == 0)
+                               blocking_io = 1;
+               }
 
                server_options(args,&argc);
-
        }
 
        args[argc++] = ".";
@@ -285,7 +292,7 @@ oom:
 static char *get_local_name(struct file_list *flist,char *name)
 {
        STRUCT_STAT st;
-       int len;
+       int e;
        extern int orig_umask;
 
        if (verbose > 2)
@@ -298,8 +305,8 @@ static char *get_local_name(struct file_list *flist,char *name)
        if (do_stat(name,&st) == 0) {
                if (S_ISDIR(st.st_mode)) {
                        if (!push_dir(name, 0)) {
-                               rprintf(FERROR,"push_dir %s : %s (1)\n",
-                                       name,strerror(errno));
+                               rprintf(FERROR, "push_dir %s failed: %s (1)\n",
+                                       full_fname(name), strerror(errno));
                                exit_cleanup(RERR_FILESELECT);
                        }
                        return NULL;
@@ -311,13 +318,12 @@ static char *get_local_name(struct file_list *flist,char *name)
                return name;
        }
 
-       len = strlen(name);
-       if ((len <= 1 || name[len-1] != '/') && flist->count <= 1)
+       if (flist->count <= 1 && ((e = strlen(name)) <= 1 || name[e-1] != '/'))
                return name;
 
        if (do_mkdir(name,0777 & ~orig_umask) != 0) {
-               rprintf(FERROR, RSYNC_NAME ": mkdir %s: %s\n",
-                       name, strerror(errno));
+               rprintf(FERROR, "mkdir %s failed: %s\n",
+                       full_fname(name), strerror(errno));
                exit_cleanup(RERR_FILEIO);
        } else {
                if (verbose > 0)
@@ -325,8 +331,8 @@ static char *get_local_name(struct file_list *flist,char *name)
        }
 
        if (!push_dir(name, 0)) {
-               rprintf(FERROR, RSYNC_NAME ": push_dir %s: %s\n",
-                       name, strerror(errno));
+               rprintf(FERROR, "push_dir %s failed: %s (2)\n",
+                       full_fname(name), strerror(errno));
                exit_cleanup(RERR_FILESELECT);
        }
 
@@ -343,13 +349,13 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
        char *dir = argv[0];
        extern int relative_paths;
        extern int recurse;
-       extern int remote_version;
 
        if (verbose > 2)
                rprintf(FINFO,"server_sender starting pid=%d\n",(int)getpid());
 
        if (!relative_paths && !push_dir(dir, 0)) {
-               rprintf(FERROR,"push_dir %s: %s (3)\n",dir,strerror(errno));
+               rprintf(FERROR, "push_dir %s failed: %s (3)\n",
+                       full_fname(dir), strerror(errno));
                exit_cleanup(RERR_FILESELECT);
        }
        argc--;
@@ -374,13 +380,15 @@ static void do_server_sender(int f_in, int f_out, int argc,char *argv[])
                exit_cleanup(0);
        }
 
+       io_start_buffering_in(f_in);
+       io_start_buffering_out(f_out);
        send_files(flist,f_out,f_in);
        io_flush();
        report(f_out);
-       if (remote_version >= 24) {
+       if (protocol_version >= 24) {
                /* final goodbye message */
-               read_int(f_in);
-       }
+               read_int(f_in);
+       }
        io_flush();
        exit_cleanup(0);
 }
@@ -396,7 +404,6 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
        extern int delete_after;
        extern int recurse;
        extern int delete_mode;
-       extern int remote_version;
 
        if (preserve_hard_links)
                init_hard_links(flist);
@@ -439,8 +446,8 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
                close(recv_pipe[1]);
                io_flush();
                /* finally we go to sleep until our parent kills us
-                  with a USR2 signal. We sleep for a short time as on
-                  some OSes a signal won't interrupt a sleep! */
+                * with a USR2 signal. We sleep for a short time as on
+                * some OSes a signal won't interrupt a sleep! */
                while (msleep(20))
                        ;
        }
@@ -449,7 +456,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
        close(error_pipe[1]);
        if (f_in != f_out) close(f_in);
 
-       io_start_buffering(f_out);
+       io_start_buffering_out(f_out);
 
        io_set_error_fd(error_pipe[0]);
 
@@ -457,7 +464,7 @@ static int do_recv(int f_in,int f_out,struct file_list *flist,char *local_name)
 
        read_int(recv_pipe[0]);
        close(recv_pipe[0]);
-       if (remote_version >= 24) {
+       if (protocol_version >= 24) {
                /* send a final goodbye message */
                write_int(f_out, -1);
        }
@@ -497,12 +504,13 @@ static void do_server_recv(int f_in, int f_out, int argc,char *argv[])
                argc--;
                argv++;
                if (!am_daemon && !push_dir(dir, 0)) {
-                       rprintf(FERROR,"push_dir %s : %s (4)\n",
-                               dir,strerror(errno));
+                       rprintf(FERROR, "push_dir %s failed: %s (4)\n",
+                               full_fname(dir), strerror(errno));
                        exit_cleanup(RERR_FILESELECT);
                }
        }
 
+       io_start_buffering_in(f_in);
        if (delete_mode && !delete_excluded)
                recv_exclude_list(f_in);
 
@@ -547,7 +555,6 @@ int child_main(int argc, char *argv[])
 void start_server(int f_in, int f_out, int argc, char *argv[])
 {
        extern int cvs_exclude;
-       extern int remote_version;
        extern int read_batch;
 
        setup_protocol(f_out, f_in);
@@ -555,7 +562,7 @@ void start_server(int f_in, int f_out, int argc, char *argv[])
        set_nonblocking(f_in);
        set_nonblocking(f_out);
 
-       if (remote_version >= 23)
+       if (protocol_version >= 23)
                io_start_multiplex_out(f_out);
 
        if (am_sender) {
@@ -581,7 +588,6 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
        struct file_list *flist = NULL;
        int status = 0, status2 = 0;
        char *local_name = NULL;
-       extern int remote_version;
        extern pid_t cleanup_child_pid;
        extern int write_batch;
        extern int read_batch;
@@ -596,26 +602,30 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
 
        setup_protocol(f_out,f_in);
 
-       if (remote_version >= 23)
+       if (protocol_version >= 23)
                io_start_multiplex_in(f_in);
 
        if (am_sender) {
                extern int cvs_exclude;
                extern int delete_mode;
                extern int delete_excluded;
+               io_start_buffering_out(f_out);
                if (cvs_exclude)
                        add_cvs_excludes();
                if (delete_mode && !delete_excluded)
                        send_exclude_list(f_out);
                if (remote_filesfrom_file)
                        filesfrom_fd = f_in;
-               if (!read_batch) /*  dw -- don't write to pipe */
+               if (!read_batch) /* don't write to pipe */
                        flist = send_file_list(f_out,argc,argv);
                if (verbose > 3)
                        rprintf(FINFO,"file list sent\n");
 
+               io_flush();
+               io_start_buffering_out(f_out);
                send_files(flist,f_out,f_in);
-               if (remote_version >= 24) {
+               io_flush();
+               if (protocol_version >= 24) {
                        /* final goodbye message */
                        read_int(f_in);
                }
@@ -626,6 +636,7 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
                        wait_process(pid, &status);
                }
                report(-1);
+               io_flush();
                exit_cleanup(status);
        }
 
@@ -860,7 +871,7 @@ static int start_client(int argc, char *argv[])
                     &f_in,&f_out);
 
        /* if we're running an rsync server on the remote host over a
-          remote shell command, we need to do the RSYNCD protocol first */
+        * remote shell command, we need to do the RSYNCD protocol first */
        if (daemon_over_rsh) {
                int tmpret;
                tmpret = start_inband_exchange(shell_user, shell_path,
@@ -878,17 +889,20 @@ static int start_client(int argc, char *argv[])
 }
 
 
-static RETSIGTYPE sigusr1_handler(int UNUSED(val)) {
+static RETSIGTYPE sigusr1_handler(UNUSED(int val))
+{
        exit_cleanup(RERR_SIGNAL);
 }
 
-static RETSIGTYPE sigusr2_handler(int UNUSED(val)) {
+static RETSIGTYPE sigusr2_handler(UNUSED(int val))
+{
        extern int log_got_error;
        if (log_got_error) _exit(RERR_PARTIAL);
        _exit(0);
 }
 
-static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
+static RETSIGTYPE sigchld_handler(UNUSED(int val))
+{
 #ifdef WNOHANG
        int cnt, status;
        pid_t pid;
@@ -899,14 +913,14 @@ static RETSIGTYPE sigchld_handler(int UNUSED(val)) {
         * zombie children, maybe that's why he did it.
         */
        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
-                /* save the child's exit status */
-                for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
-                         if (pid_stat_table[cnt].pid == 0) {
-                                  pid_stat_table[cnt].pid = pid;
-                                  pid_stat_table[cnt].status = status;
-                                  break;
-                         }
-                }
+               /* save the child's exit status */
+               for (cnt = 0; cnt < MAXCHILDPROCS; cnt++) {
+                       if (pid_stat_table[cnt].pid == 0) {
+                               pid_stat_table[cnt].pid = pid;
+                               pid_stat_table[cnt].status = status;
+                               break;
+                       }
+               }
        }
 #endif
 }
@@ -946,7 +960,7 @@ const char *get_panic_action(void)
  * should just look at the environment variable, but I'm a bit leery
  * of a signal sending us into a busy loop.
  **/
-static RETSIGTYPE rsync_panic_handler(int UNUSED(whatsig))
+static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
 {
        char cmd_buf[300];
        int ret;
@@ -997,7 +1011,7 @@ int main(int argc,char *argv[])
        }
 
        /* we set a 0 umask so that correct file permissions can be
-          carried across */
+        * carried across */
        orig_umask = (int)umask(0);
 
        if (!parse_arguments(&argc, (const char ***) &argv, 1)) {
@@ -1016,9 +1030,9 @@ int main(int argc,char *argv[])
        signal(SIGPIPE, SIG_IGN);
 
        /* Initialize push_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. */
+        * (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);
 
        if (write_batch && !am_server) {
@@ -1057,6 +1071,5 @@ int main(int argc,char *argv[])
        else
                exit_cleanup(ret);
 
-       exit(ret);
-       /* NOTREACHED */
+       return ret;
 }