From 9a2bb7fe9cf4d7408c5dcb83874af0a72f093dae Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Fri, 22 Mar 2002 04:50:20 +0000 Subject: [PATCH] J.W. Schultz: Attached is a patch against 2.5.4pre1 CVS current to add the --link-dest option so rsync will create hardlinks for unchanged regular files to a directory on the destination. This is like --compare-dest except that the result is not a sparse tree. Also included is extension to --(ex|in)clude-from to allow - for stdin. --- jw_rsync3.diff | 199 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 jw_rsync3.diff diff --git a/jw_rsync3.diff b/jw_rsync3.diff new file mode 100644 index 0000000..38726f5 --- /dev/null +++ b/jw_rsync3.diff @@ -0,0 +1,199 @@ +Please CC me. I'm not subscribed. + +Attached is a patch against 2.5.4pre1 CVS current to add the +--link-dest option so rsync will create hardlinks for +unchanged regular files to a directory on the destination. +This is like --compare-dest except that the result is not a +sparse tree. + +Also included is extension to --(ex|in)clude-from to allow - +for stdin. + +Could one of the maintainers please add this to the +mainline? + +Thanks to Dave Dykstra for feedback on this. + +-- +________________________________________________________________ + J.W. Schultz Pegasystems Technologies + email address: jw@pegasys.ws + + Remember Cernan and Schmitt +? options-merge.c +Index: exclude.c +=================================================================== +RCS file: /cvsroot/rsync/exclude.c,v +retrieving revision 1.42 +diff -u -r1.42 exclude.c +--- exclude.c 18 Feb 2002 19:10:28 -0000 1.42 ++++ exclude.c 21 Mar 2002 23:31:25 -0000 +@@ -219,8 +219,14 @@ + int fatal, int include) + { + struct exclude_struct **list=list1; +- FILE *f = fopen(fname,"r"); ++ FILE *f; + char line[MAXPATHLEN]; ++ ++ if (strcmp(fname, "-")) { ++ f = fopen(fname,"r"); ++ } else { ++ f = fdopen(0, "r"); ++ } + if (!f) { + if (fatal) { + rsyserr(FERROR, errno, +Index: generator.c +=================================================================== +RCS file: /cvsroot/rsync/generator.c,v +retrieving revision 1.37 +diff -u -r1.37 generator.c +--- generator.c 19 Mar 2002 20:16:42 -0000 1.37 ++++ generator.c 21 Mar 2002 23:31:26 -0000 +@@ -41,6 +41,7 @@ + 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 @@ + 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 */ +@@ -382,6 +392,17 @@ + statret = -1; + if (statret == -1) + errno = saveerrno; ++#if HAVE_LINK ++ else if (link_dest) ++ 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: options.c +=================================================================== +RCS file: /cvsroot/rsync/options.c,v +retrieving revision 1.89 +diff -u -r1.89 options.c +--- options.c 19 Mar 2002 20:16:42 -0000 1.89 ++++ options.c 21 Mar 2002 23:31:27 -0000 +@@ -113,6 +113,7 @@ + char *rsync_path = RSYNC_PATH; + char *backup_dir = NULL; + int rsync_port = RSYNC_PORT; ++int link_dest = 0; + + int verbose = 0; + int quiet = 0; +@@ -282,7 +283,7 @@ + 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, +@@ -341,6 +342,7 @@ + {"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 }, +@@ -562,6 +564,19 @@ + /* 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 +@@ -785,7 +800,7 @@ + * 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: rsync.yo +=================================================================== +RCS file: /cvsroot/rsync/rsync.yo,v +retrieving revision 1.95 +diff -u -r1.95 rsync.yo +--- rsync.yo 6 Feb 2002 21:20:49 -0000 1.95 ++++ rsync.yo 21 Mar 2002 23:31:28 -0000 +@@ -261,6 +261,7 @@ + --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 +@@ -531,6 +532,7 @@ + option, but instead it adds all exclude patterns listed in the file + FILE to the exclude list. Blank lines in FILE and lines starting with + ';' or '#' are ignored. ++If \fIFILE\fP is \fB-\fP the list will be read from standard input. + + dit(bf(--include=PATTERN)) This option tells rsync to not exclude the + specified pattern of filenames. This is useful as it allows you to +@@ -541,6 +543,7 @@ + + dit(bf(--include-from=FILE)) This specifies a list of include patterns + from a file. ++If \fIFILE\fP is \fB-\fP the list will be read from standard input. + + dit(bf(-C, --cvs-exclude)) This is a useful shorthand for excluding a + broad range of files that you often don't want to transfer between +@@ -595,6 +598,11 @@ + --partial because partially transferred files will remain in the new + 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 \fB--compare-dest\fP but ++also will create hard links from \fIDIR\fP 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 -- 2.34.1