*** empty log message ***
[rsync/rsync.git] / main.c
diff --git a/main.c b/main.c
index 3fbdea1..837d309 100644 (file)
--- a/main.c
+++ b/main.c
@@ -30,6 +30,8 @@ char *backup_suffix = BACKUP_SUFFIX;
 static char *rsync_path = RSYNC_NAME;
 
 int make_backups = 0;
+int whole_file = 0;
+int copy_links = 0;
 int preserve_links = 0;
 int preserve_hard_links = 0;
 int preserve_perms = 0;
@@ -115,6 +117,10 @@ static void server_options(char **args,int *argc)
     argstr[x++] = 'n';
   if (preserve_links)
     argstr[x++] = 'l';
+  if (copy_links)
+    argstr[x++] = 'L';
+  if (whole_file)
+    argstr[x++] = 'W';
   if (preserve_hard_links)
     argstr[x++] = 'H';
   if (preserve_uid)
@@ -152,6 +158,11 @@ static void server_options(char **args,int *argc)
     args[ac++] = bsize;
   }    
 
+  if (strcmp(backup_suffix, BACKUP_SUFFIX)) {
+         args[ac++] = "--suffix";
+         args[ac++] = backup_suffix;
+  }
+
   if (delete_mode)
     args[ac++] = "--delete";
 
@@ -160,11 +171,11 @@ static void server_options(char **args,int *argc)
 
 
 
-int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
+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;
-  char *tok,*p;
+  int i,argc=0, ret;
+  char *tok,*p,*dir=NULL;
 
   if (!local_server) {
     if (!cmd)
@@ -200,7 +211,7 @@ int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
   server_options(args,&argc);
 
   if (path && *path) {
-    char *dir = strdup(path);
+    dir = strdup(path);
     p = strrchr(dir,'/');
     if (p && !relative_paths) {
       *p = 0;
@@ -226,7 +237,10 @@ int do_cmd(char *cmd,char *machine,char *user,char *path,int *f_in,int *f_out)
     fprintf(FERROR,"\n");
   }
 
-  return piped_child(args,f_in,f_out);
+  ret = piped_child(args,f_in,f_out);
+  if (dir) free(dir);
+
+  return ret;
 
 oom:
   out_of_memory("do_cmd");
@@ -404,6 +418,7 @@ static void usage(FILE *f)
   fprintf(f,"-b, --backup             make backups (default ~ extension)\n");
   fprintf(f,"-u, --update             update only (don't overwrite newer files)\n");
   fprintf(f,"-l, --links              preserve soft links\n");
+  fprintf(f,"-L, --copy-links         treat soft links like regular files\n");
   fprintf(f,"-H, --hard-links         preserve hard links\n");
   fprintf(f,"-p, --perms              preserve permissions\n");
   fprintf(f,"-o, --owner              preserve owner (root only)\n");
@@ -412,6 +427,7 @@ static void usage(FILE *f)
   fprintf(f,"-t, --times              preserve times\n");  
   fprintf(f,"-S, --sparse             handle sparse files efficiently\n");
   fprintf(f,"-n, --dry-run            show what would have been transferred\n");
+  fprintf(f,"-W, --whole-file         copy whole files, no incremental checks\n");
   fprintf(f,"-x, --one-file-system    don't cross filesystem boundaries\n");
   fprintf(f,"-B, --block-size SIZE    checksum blocking size\n");  
   fprintf(f,"-e, --rsh COMMAND        specify rsh replacement\n");
@@ -433,7 +449,7 @@ static void usage(FILE *f)
 enum {OPT_VERSION,OPT_SUFFIX,OPT_SENDER,OPT_SERVER,OPT_EXCLUDE,
       OPT_EXCLUDE_FROM,OPT_DELETE,OPT_RSYNC_PATH};
 
-static char *short_options = "oblHpguDCtcahvrRIxnSe:B:z";
+static char *short_options = "oblLWHpguDCtcahvrRIxnSe:B:z";
 
 static struct option long_options[] = {
   {"version",     0,     0,    OPT_VERSION},
@@ -459,6 +475,8 @@ static struct option long_options[] = {
   {"devices",     0,     0,    'D'},
   {"perms",       0,     0,    'p'},
   {"links",       0,     0,    'l'},
+  {"copy-links",  0,     0,    'L'},
+  {"whole-file",  0,     0,    'W'},
   {"hard-links",  0,     0,    'H'},
   {"owner",       0,     0,    'o'},
   {"group",       0,     0,    'g'},
@@ -469,6 +487,10 @@ static struct option long_options[] = {
   {"compress",   0,     0,    'z'},
   {0,0,0,0}};
 
+RETSIGTYPE sigusr1_handler(int val) {
+       exit_cleanup(1);
+}
+
 int main(int argc,char *argv[])
 {
     int pid, status = 0, status2 = 0;
@@ -483,6 +505,13 @@ int main(int argc,char *argv[])
     struct file_list *flist;
     char *local_name = NULL;
 
+#ifdef SETPGRP_VOID
+    setpgrp();
+#else
+    setpgrp(0,0);
+#endif
+    signal(SIGUSR1, sigusr1_handler);
+
     starttime = time(NULL);
     am_root = (getuid() == 0);
 
@@ -553,14 +582,23 @@ int main(int argc,char *argv[])
          break;
 
        case 'l':
-#if SUPPORT_LINKS
          preserve_links=1;
-#endif
+         break;
+
+       case 'L':
+         copy_links=1;
+         break;
+
+       case 'W':
+         whole_file=1;
          break;
 
        case 'H':
 #if SUPPORT_HARD_LINKS
          preserve_hard_links=1;
+#else 
+         fprintf(FERROR,"ERROR: hard links not supported on this platform\n");
+         exit_cleanup(1);
 #endif
          break;
 
@@ -657,6 +695,13 @@ int main(int argc,char *argv[])
     if (dry_run)
       verbose = MAX(verbose,1);
 
+#ifndef SUPPORT_LINKS
+    if (!am_server && preserve_links) {
+           fprintf(FERROR,"ERROR: symbolic links not supported\n");
+           exit_cleanup(1);
+    }
+#endif
+
     if (am_server) {
       setup_protocol(STDOUT_FILENO,STDIN_FILENO);
        
@@ -730,8 +775,10 @@ int main(int argc,char *argv[])
 
     setup_protocol(f_out,f_in);
 
+#if HAVE_SETLINEBUF
     setlinebuf(FINFO);
     setlinebuf(FERROR);
+#endif
 
     if (verbose > 3) 
       fprintf(FERROR,"parent=%d child=%d sender=%d recurse=%d\n",
@@ -771,3 +818,4 @@ int main(int argc,char *argv[])
 
     return status | status2;
 }
+