Add --link-dest option from J.W. Schultz.
authorDavid Dykstra <dwd@samba.org>
Thu, 29 Aug 2002 14:44:55 +0000 (14:44 +0000)
committerDavid Dykstra <dwd@samba.org>
Thu, 29 Aug 2002 14:44:55 +0000 (14:44 +0000)
NEWS
generator.c
options.c
rsync.yo

diff --git a/NEWS b/NEWS
index 34e424fff741d66518c295a8e619cdc5892a081e..fe1e75f1a21b740cfbb06e97d7f2c3b0d5528cd0 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -18,6 +18,10 @@ rsync changes since last release
     * If the file name given to --include-from or --exclude-from is "-",
       rsync will read from standard input. (J.W. Schultz)
 
+    * New option --link-dest which is like --compare-dest except that
+      unchanged files are hard-linked in to the destination directory.
+      (J.W. Schultz)
+
   BUG FIXES:
   
     * Fix "forward name lookup failed" errors on AIX 4.3.3.  (John
index dd3eef66250799c591df2783e872533b2ef8fa50..f3849a0778282bc34a13f8d5cc098f3c040b1f0a 100644 (file)
@@ -41,6 +41,7 @@ extern int remote_version;
 extern int always_checksum;
 extern int modify_window;
 extern char *compare_dest;
+extern int link_dest;
 
 
 /* choose whether to skip a particular file */
@@ -50,6 +51,15 @@ static int skip_file(char *fname,
        if (st->st_size != file->length) {
                return 0;
        }
+       if (link_dest) {
+               if((st->st_mode & ~_S_IFMT) !=  (file->mode & ~_S_IFMT)) {
+                       return 0;
+               }
+               if (st->st_uid != file->uid || st->st_gid != file->gid) {
+                       return 0;
+               }
+       }
+
        
        /* if always checksum is set then we use the checksum instead 
           of the file time to determine whether to sync */
@@ -356,6 +366,18 @@ void recv_generator(char *fname, struct file_list *flist, int i, int f_out)
                        statret = -1;
                if (statret == -1)
                        errno = saveerrno;
+#if HAVE_LINK
+               else if (link_dest && !dry_run) {
+                       if (do_link(fnamecmpbuf, fname) != 0) {
+                               if (verbose > 0)
+                                       rprintf(FINFO,"link %s => %s : %s\n",
+                                               fnamecmpbuf,
+                                               fname,
+                                               strerror(errno));
+                       }
+                       fnamecmp = fnamecmpbuf;
+               }
+#endif
                else
                        fnamecmp = fnamecmpbuf;
        }
index 7ed88232a1b63c4695ff19a30a97ed909d25a5eb..06b442c805dce76ce5050188a94b53553990f6d0 100644 (file)
--- a/options.c
+++ b/options.c
@@ -115,6 +115,7 @@ char *password_file = NULL;
 char *rsync_path = RSYNC_PATH;
 char *backup_dir = NULL;
 int rsync_port = RSYNC_PORT;
+int link_dest = 0;
 
 int verbose = 0;
 int quiet = 0;
@@ -289,7 +290,7 @@ enum {OPT_VERSION = 1000, OPT_SUFFIX, OPT_SENDER, OPT_SERVER, OPT_EXCLUDE,
       OPT_EXCLUDE_FROM, OPT_DELETE, OPT_DELETE_EXCLUDED, OPT_NUMERIC_IDS,
       OPT_RSYNC_PATH, OPT_FORCE, OPT_TIMEOUT, OPT_DAEMON, OPT_CONFIG, OPT_PORT,
       OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_STATS, OPT_PARTIAL, OPT_PROGRESS,
-      OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST,
+      OPT_COPY_UNSAFE_LINKS, OPT_SAFE_LINKS, OPT_COMPARE_DEST, OPT_LINK_DEST,
       OPT_LOG_FORMAT, OPT_PASSWORD_FILE, OPT_SIZE_ONLY, OPT_ADDRESS,
       OPT_DELETE_AFTER, OPT_EXISTING, OPT_MAX_DELETE, OPT_BACKUP_DIR, 
       OPT_IGNORE_ERRORS, OPT_BWLIMIT, OPT_BLOCKING_IO,
@@ -348,6 +349,7 @@ static struct poptOption long_options[] = {
   {"timeout",          0,  POPT_ARG_INT,    &io_timeout , 0, 0, 0 },
   {"temp-dir",        'T', POPT_ARG_STRING, &tmpdir , 0, 0, 0 },
   {"compare-dest",     0,  POPT_ARG_STRING, &compare_dest , 0, 0, 0 },
+  {"link-dest",        0,  POPT_ARG_STRING, 0,               OPT_LINK_DEST, 0, 0 },
   /* TODO: Should this take an optional int giving the compression level? */
   {"compress",        'z', POPT_ARG_NONE,   &do_compression , 0, 0, 0 },
   {"daemon",           0,  POPT_ARG_NONE,   &am_daemon , 0, 0, 0 },
@@ -591,6 +593,19 @@ int parse_arguments(int *argc, const char ***argv, int frommain)
                        /* popt stores the filename in batch_prefix for us */
                        read_batch = 1;
                        break;
+               case OPT_LINK_DEST:
+#if HAVE_LINK
+                       compare_dest = poptGetOptArg(pc);
+                       link_dest = 1;
+                       break;
+#else
+                       snprintf(err_buf,sizeof(err_buf),
+                                 "hard links are not supported on this %s\n",
+                                am_server ? "server" : "client");
+                       rprintf(FERROR,"ERROR: hard links not supported on this platform\n");
+                       return 0;
+#endif
+
 
                default:
                         /* FIXME: If --daemon is specified, then errors for later
@@ -827,7 +842,7 @@ void server_options(char **args,int *argc)
                 *   and it may be an older version that doesn't know this
                 *   option, so don't send it if client is the sender.
                 */
-               args[ac++] = "--compare-dest";
+               args[ac++] = link_dest ? "--link-dest" : "--compare-dest";
                args[ac++] = compare_dest;
        }
 
index 93b06f92def0856794fe63eae0448dab360341dc..21d69624d233bfe03104052fd8decc5eb522326a 100644 (file)
--- a/rsync.yo
+++ b/rsync.yo
@@ -324,6 +324,7 @@ verb(
      --modify-window=NUM     Timestamp window (seconds) for file match (default=0)
  -T  --temp-dir=DIR          create temporary files in directory DIR
      --compare-dest=DIR      also compare destination files relative to DIR
+     --link-dest=DIR         create hardlinks to DIR for unchanged files
  -P                          equivalent to --partial --progress
  -z, --compress              compress file data
      --exclude=PATTERN       exclude files matching PATTERN
@@ -686,6 +687,11 @@ files that haven't changed).  This option increases the usefulness of
 temporary destination until they have a chance to be completed.  If DIR is
 a relative path, it is relative to the destination directory.
 
+dit(bf(--link-dest=DIR)) This option behaves like bf(--compare-dest) but
+also will create hard links from em(DIR) to the destination directory for
+unchanged files.  Files with changed ownership or permissions will not be
+linked.
+
 dit(bf(-z, --compress)) With this option, rsync compresses any data from
 the files that it sends to the destination machine.  This
 option is useful on slow links.  The compression method used is the