some code cleanup in preparation for a cleaner client/server split
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index 33496cc..ccf5895 100644 (file)
--- a/main.c
+++ b/main.c
@@ -58,10 +58,12 @@ int force_delete = 0;
 int io_timeout = 0;
 int io_error = 0;
 
+static char *shell_cmd;
+
 extern int csum_length;
 
 int am_server = 0;
-static int sender;
+int am_sender;
 int recurse = 0;
 
 static void usage(FILE *f);
@@ -73,7 +75,7 @@ static void report(int f)
   
   if (!verbose) return;
 
-  if (am_server && sender) {
+  if (am_server && am_sender) {
     write_longint(f,read_total());
     write_longint(f,write_total());
     write_longint(f,total_size);
@@ -81,7 +83,7 @@ static void report(int f)
     return;
   }
     
-  if (sender) {
+  if (am_sender) {
     in = read_total();
     out = write_total();
     tsize = total_size;
@@ -91,17 +93,10 @@ static void report(int f)
     tsize = read_longint(f);
   }
 
-#if HAVE_LONGLONG
-  printf("wrote %lld bytes  read %lld bytes  %g bytes/sec\n",
-        (long long)out,(long long)in,(in+out)/(0.5 + (t-starttime)));
-  printf("total size is %lld  speedup is %g\n",
-        (long long)tsize,(1.0*tsize)/(in+out));
-#else
-  printf("wrote %ld bytes  read %ld bytes  %g bytes/sec\n",
-        (long)out,(long)in,(in+out)/(0.5 + (t-starttime)));
-  printf("total size is %ld  speedup is %g\n",
-        (long)tsize,(1.0*tsize)/(in+out));
-#endif
+  printf("wrote %.0f bytes  read %.0f bytes  %.2f bytes/sec\n",
+        (double)out,(double)in,(in+out)/(0.5 + (t-starttime)));
+  printf("total size is %.0f  speedup is %.2f\n",
+        (double)tsize,(1.0*tsize)/(in+out));
 }
 
 
@@ -115,7 +110,7 @@ static void server_options(char **args,int *argc)
 
   args[ac++] = "--server";
 
-  if (!sender)
+  if (!am_sender)
     args[ac++] = "--sender";
 
   x = 1;
@@ -202,65 +197,70 @@ static void server_options(char **args,int *argc)
 
 static int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
 {
-  char *args[100];
-  int i,argc=0, ret;
-  char *tok,*dir=NULL;
-
-  if (!local_server) {
-    if (!cmd)
-      cmd = getenv(RSYNC_RSH_ENV);
-    if (!cmd)
-      cmd = RSYNC_RSH;
-    cmd = strdup(cmd);
-    if (!cmd) 
-      goto oom;
-
-    for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
-      args[argc++] = tok;
-    }
+       char *args[100];
+       int i,argc=0, ret;
+       char *tok,*dir=NULL;
+
+       if (!local_server) {
+               if (!cmd)
+                       cmd = getenv(RSYNC_RSH_ENV);
+               if (!cmd)
+                       cmd = RSYNC_RSH;
+               cmd = strdup(cmd);
+               if (!cmd) 
+                       goto oom;
+
+               for (tok=strtok(cmd," ");tok;tok=strtok(NULL," ")) {
+                       args[argc++] = tok;
+               }
 
 #if HAVE_REMSH
-    /* remsh (on HPUX) takes the arguments the other way around */
-    args[argc++] = machine;
-    if (user) {
-      args[argc++] = "-l";
-      args[argc++] = user;
-    }
+               /* remsh (on HPUX) takes the arguments the other way around */
+               args[argc++] = machine;
+               if (user) {
+                       args[argc++] = "-l";
+                       args[argc++] = user;
+               }
 #else
-    if (user) {
-      args[argc++] = "-l";
-      args[argc++] = user;
-    }
-    args[argc++] = machine;
+               if (user) {
+                       args[argc++] = "-l";
+                       args[argc++] = user;
+               }
+               args[argc++] = machine;
 #endif
-  }
 
-  args[argc++] = rsync_path;
+               args[argc++] = rsync_path;
 
-  server_options(args,&argc);
+               server_options(args,&argc);
+       }
 
-  args[argc++] = ".";
+       args[argc++] = ".";
 
-  if (path && *path) 
-         args[argc++] = path;
+       if (path && *path) 
+               args[argc++] = path;
 
-  args[argc] = NULL;
+       args[argc] = NULL;
 
-  if (verbose > 3) {
-    fprintf(FINFO,"cmd=");
-    for (i=0;i<argc;i++)
-      fprintf(FINFO,"%s ",args[i]);
-    fprintf(FINFO,"\n");
-  }
+       if (verbose > 3) {
+               fprintf(FINFO,"cmd=");
+               for (i=0;i<argc;i++)
+                       fprintf(FINFO,"%s ",args[i]);
+               fprintf(FINFO,"\n");
+       }
+
+       if (local_server) {
+               ret = local_child(argc, args, f_in, f_out);
+       } else {
+               ret = piped_child(args,f_in,f_out);
+       }
 
-  ret = piped_child(args,f_in,f_out);
-  if (dir) free(dir);
+       if (dir) free(dir);
 
-  return ret;
+       return ret;
 
 oom:
-  out_of_memory("do_cmd");
-  return 0; /* not reached */
+       out_of_memory("do_cmd");
+       return 0; /* not reached */
 }
 
 
@@ -268,9 +268,9 @@ oom:
 
 static char *get_local_name(struct file_list *flist,char *name)
 {
-  struct stat st;
+  STRUCT_STAT st;
 
-  if (stat(name,&st) == 0) {
+  if (do_stat(name,&st) == 0) {
     if (S_ISDIR(st.st_mode)) {
       if (chdir(name) != 0) {
        fprintf(FERROR,"chdir %s : %s (1)\n",name,strerror(errno));
@@ -291,7 +291,7 @@ static char *get_local_name(struct file_list *flist,char *name)
   if (!name) 
     return NULL;
 
-  if (mkdir(name,0777 & ~orig_umask) != 0) {
+  if (do_mkdir(name,0777 & ~orig_umask) != 0) {
     fprintf(FERROR,"mkdir %s : %s (1)\n",name,strerror(errno));
     exit_cleanup(1);
   } else {
@@ -420,6 +420,131 @@ void do_server_recv(int argc,char *argv[])
 }
 
 
+void start_server(int argc, char *argv[])
+{
+      setup_protocol(STDOUT_FILENO,STDIN_FILENO);
+       
+      if (am_sender) {
+             recv_exclude_list(STDIN_FILENO);
+             if (cvs_exclude)
+                     add_cvs_excludes();
+             do_server_sender(argc,argv);
+      } else {
+             do_server_recv(argc,argv);
+      }
+      exit_cleanup(0);
+}
+
+int start_client(int argc, char *argv[])
+{
+       char *p;
+       char *shell_machine = NULL;
+       char *shell_path = NULL;
+       char *shell_user = NULL;
+       int pid, status = 0, status2 = 0;
+       int f_in,f_out;
+       struct file_list *flist;
+       char *local_name = NULL;
+
+       p = strchr(argv[0],':');
+
+       if (p) {
+               am_sender = 0;
+               *p = 0;
+               shell_machine = argv[0];
+               shell_path = p+1;
+               argc--;
+               argv++;
+       } else {
+               am_sender = 1;
+               
+               p = strchr(argv[argc-1],':');
+               if (!p) {
+                       local_server = 1;
+               }
+
+               if (local_server) {
+                       shell_machine = NULL;
+                       shell_path = argv[argc-1];
+               } else {
+                       *p = 0;
+                       shell_machine = argv[argc-1];
+                       shell_path = p+1;
+               }
+               argc--;
+       }
+       
+       if (shell_machine) {
+               p = strchr(shell_machine,'@');
+               if (p) {
+                       *p = 0;
+                       shell_user = shell_machine;
+                       shell_machine = p+1;
+               }
+       }
+
+       if (verbose > 3) {
+               fprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
+                       shell_cmd?shell_cmd:"",
+                       shell_machine?shell_machine:"",
+                       shell_user?shell_user:"",
+                       shell_path?shell_path:"");
+       }
+       
+       if (!am_sender && argc != 1) {
+               usage(FERROR);
+               exit_cleanup(1);
+       }
+       
+       pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
+       
+       setup_protocol(f_out,f_in);
+       
+#if HAVE_SETLINEBUF
+       setlinebuf(FINFO);
+       setlinebuf(FERROR);
+#endif
+       
+       if (verbose > 3) 
+               fprintf(FINFO,"parent=%d child=%d sender=%d recurse=%d\n",
+                       (int)getpid(),pid,am_sender,recurse);
+       
+       if (am_sender) {
+               if (cvs_exclude)
+                       add_cvs_excludes();
+               if (delete_mode) 
+                       send_exclude_list(f_out);
+               flist = send_file_list(f_out,argc,argv);
+               if (verbose > 3) 
+                       fprintf(FINFO,"file list sent\n");
+               send_files(flist,f_out,f_in);
+               if (verbose > 3)
+                       fprintf(FINFO,"waiting on %d\n",pid);
+               waitpid(pid, &status, 0);
+               report(-1);
+               exit_cleanup(status);
+       }
+       
+       send_exclude_list(f_out);
+       
+       flist = recv_file_list(f_in);
+       if (!flist || flist->count == 0) {
+               fprintf(FINFO,"nothing to do\n");
+               exit_cleanup(0);
+       }
+       
+       local_name = get_local_name(flist,argv[0]);
+       
+       status2 = do_recv(f_in,f_out,flist,local_name);
+       
+       report(f_in);
+       
+       waitpid(pid, &status, 0);
+       
+       return status | status2;
+}
+
+
 static void usage(FILE *f)
 {
   fprintf(f,"rsync version %s Copyright Andrew Tridgell and Paul Mackerras\n\n",
@@ -517,28 +642,11 @@ RETSIGTYPE sigusr1_handler(int val) {
        exit_cleanup(1);
 }
 
-int main(int argc,char *argv[])
+
+static void parse_arguments(int argc, char *argv[])
 {
-    int pid, status = 0, status2 = 0;
     int opt;
     int option_index;
-    char *shell_cmd = NULL;
-    char *shell_machine = NULL;
-    char *shell_path = NULL;
-    char *shell_user = NULL;
-    char *p;
-    int f_in,f_out;
-    struct file_list *flist;
-    char *local_name = NULL;
-
-    signal(SIGUSR1, sigusr1_handler);
-
-    starttime = time(NULL);
-    am_root = (getuid() == 0);
-
-    /* we set a 0 umask so that correct file permissions can be
-       carried across */
-    orig_umask = (int)umask(0);
 
     while ((opt = getopt_long(argc, argv, 
                              short_options, long_options, &option_index)) 
@@ -682,7 +790,7 @@ int main(int argc,char *argv[])
            usage(FERROR);
            exit_cleanup(1);
          }
-         sender = 1;
+         am_sender = 1;
          break;
 
        case 'r':
@@ -718,10 +826,26 @@ int main(int argc,char *argv[])
          exit_cleanup(1);
        }
     }
+}
+
+int main(int argc,char *argv[])
+{
+
+    signal(SIGUSR1, sigusr1_handler);
+
+    starttime = time(NULL);
+    am_root = (getuid() == 0);
+
+    /* we set a 0 umask so that correct file permissions can be
+       carried across */
+    orig_umask = (int)umask(0);
+
+    parse_arguments(argc, argv);
 
-    while (optind--) {
+    while (optind) {
       argc--;
       argv++;
+      optind--;
     }
 
     signal(SIGCHLD,SIG_IGN);
@@ -740,17 +864,7 @@ int main(int argc,char *argv[])
 #endif
 
     if (am_server) {
-      setup_protocol(STDOUT_FILENO,STDIN_FILENO);
-       
-      if (sender) {
-       recv_exclude_list(STDIN_FILENO);
-       if (cvs_exclude)
-         add_cvs_excludes();
-       do_server_sender(argc,argv);
-      } else {
-       do_server_recv(argc,argv);
-      }
-      exit_cleanup(0);
+           start_server(argc, argv);
     }
 
     if (argc < 2) {
@@ -758,101 +872,6 @@ int main(int argc,char *argv[])
       exit_cleanup(1);
     }
 
-    p = strchr(argv[0],':');
-
-    if (p) {
-      sender = 0;
-      *p = 0;
-      shell_machine = argv[0];
-      shell_path = p+1;
-      argc--;
-      argv++;
-    } else {
-      sender = 1;
-
-      p = strchr(argv[argc-1],':');
-      if (!p) {
-       local_server = 1;
-      }
-
-      if (local_server) {
-       shell_machine = NULL;
-       shell_path = argv[argc-1];
-      } else {
-       *p = 0;
-       shell_machine = argv[argc-1];
-       shell_path = p+1;
-      }
-      argc--;
-    }
-
-    if (shell_machine) {
-      p = strchr(shell_machine,'@');
-      if (p) {
-       *p = 0;
-       shell_user = shell_machine;
-       shell_machine = p+1;
-      }
-    }
-
-    if (verbose > 3) {
-      fprintf(FINFO,"cmd=%s machine=%s user=%s path=%s\n",
-             shell_cmd?shell_cmd:"",
-             shell_machine?shell_machine:"",
-             shell_user?shell_user:"",
-             shell_path?shell_path:"");
-    }
-    
-    if (!sender && argc != 1) {
-      usage(FERROR);
-      exit_cleanup(1);
-    }
-
-    pid = do_cmd(shell_cmd,shell_machine,shell_user,shell_path,&f_in,&f_out);
-
-    setup_protocol(f_out,f_in);
-
-#if HAVE_SETLINEBUF
-    setlinebuf(FINFO);
-    setlinebuf(FERROR);
-#endif
-
-    if (verbose > 3) 
-      fprintf(FINFO,"parent=%d child=%d sender=%d recurse=%d\n",
-             (int)getpid(),pid,sender,recurse);
-
-    if (sender) {
-      if (cvs_exclude)
-       add_cvs_excludes();
-      if (delete_mode) 
-       send_exclude_list(f_out);
-      flist = send_file_list(f_out,argc,argv);
-      if (verbose > 3) 
-       fprintf(FINFO,"file list sent\n");
-      send_files(flist,f_out,f_in);
-      if (verbose > 3)
-       fprintf(FINFO,"waiting on %d\n",pid);
-      waitpid(pid, &status, 0);
-      report(-1);
-      exit_cleanup(status);
-    }
-
-    send_exclude_list(f_out);
-
-    flist = recv_file_list(f_in);
-    if (!flist || flist->count == 0) {
-      fprintf(FINFO,"nothing to do\n");
-      exit_cleanup(0);
-    }
-
-    local_name = get_local_name(flist,argv[0]);
-
-    status2 = do_recv(f_in,f_out,flist,local_name);
-
-    report(f_in);
-
-    waitpid(pid, &status, 0);
-
-    return status | status2;
+    return start_client(argc, argv);
 }