This patch adds the --link-by-hash=DIR option, which hard links received
files in a link farm arranged by MD4 file hash. The result is that the system
will only store one copy of the unique contents of each file, regardless of
the file's name.
This patch adds the --link-by-hash=DIR option, which hard links received
files in a link farm arranged by MD4 file hash. The result is that the system
will only store one copy of the unique contents of each file, regardless of
the file's name.
@@ -35,7 +35,7 @@ OBJS1=rsync.o generator.o receiver.o cle
main.o checksum.o match.o syscall.o log.o backup.o
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
@@ -35,7 +35,7 @@ OBJS1=rsync.o generator.o receiver.o cle
main.o checksum.o match.o syscall.o log.o backup.o
OBJS2=options.o flist.o io.o compat.o hlink.o token.o uidlist.o socket.o \
-OBJS3=progress.o pipe.o
+OBJS3=progress.o pipe.o hashlink.o
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
-OBJS3=progress.o pipe.o
+OBJS3=progress.o pipe.o hashlink.o
DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o
popt_OBJS=popt/findme.o popt/popt.o popt/poptconfig.o \
popt/popthelp.o popt/poptparse.o
+ asprintf(&hashfile->name,"%s/%s",hashname,
+ di->d_name);
+ if (do_stat(hashfile->name,&st) == -1) {
+ asprintf(&hashfile->name,"%s/%s",hashname,
+ di->d_name);
+ if (do_stat(hashfile->name,&st) == -1) {
-+ if (file->length == 0) {
-+ return robust_rename(fnametmp,fname,0644);
-+ }
++ if (file->length == 0)
++ return robust_rename(fnametmp, fname, NULL, 0644);
+ }
+ free(dirname);
+
+ if (do_mkdir(hashname, 0755) == -1 && errno != EEXIST) {
+ rsyserr(FERROR, errno, "mkdir failed: %s", hashname);
+ free(hashname);
+ }
+ free(dirname);
+
+ if (do_mkdir(hashname, 0755) == -1 && errno != EEXIST) {
+ rsyserr(FERROR, errno, "mkdir failed: %s", hashname);
+ free(hashname);
+ } else {
+ rsyserr(FERROR, errno, "link \"%s\" -> \"%s\"",
+ linkname, full_fname(fname));
+ } else {
+ rsyserr(FERROR, errno, "link \"%s\" -> \"%s\"",
+ linkname, full_fname(fname));
+ rprintf(FINFO, "link-by-hash (new): %s -> \"%s\"\n",
+ full_fname(fname),linkname);
+
+ rprintf(FINFO, "link-by-hash (new): %s -> \"%s\"\n",
+ full_fname(fname),linkname);
+
+ if (rc != 0) {
+ rsyserr(FERROR, errno, "rename \"%s\" -> \"%s\"",
+ full_fname(fnametmp), full_fname(fname));
+ if (rc != 0) {
+ rsyserr(FERROR, errno, "rename \"%s\" -> \"%s\"",
+ full_fname(fnametmp), full_fname(fname));
---- orig/options.c 2005-02-14 02:45:10
-+++ options.c 2005-02-14 02:52:09
-@@ -132,6 +132,7 @@ char *log_format = NULL;
- char *password_file = NULL;
- char *rsync_path = RSYNC_PATH;
- char *backup_dir = NULL;
+--- old/options.c
++++ new/options.c
+@@ -145,6 +145,7 @@ char *backup_suffix = NULL;
+ char *tmpdir = NULL;
+ char *partial_dir = NULL;
+ char *basis_dir[MAX_BASIS_DIRS+1];
- char backup_dir_buf[MAXPATHLEN];
- int rsync_port = 0;
- int compare_dest = 0;
-@@ -307,6 +308,7 @@ void usage(enum logcode F)
+ char *config_file = NULL;
+ char *shell_cmd = NULL;
+ char *logfile_name = NULL;
+@@ -349,6 +350,7 @@ void usage(enum logcode F)
rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
+ rprintf(F," --link-by-hash=DIR create hardlinks by hash into DIR\n");
rprintf(F," -z, --compress compress file data during the transfer\n");
rprintf(F," --compare-dest=DIR also compare destination files relative to DIR\n");
rprintf(F," --copy-dest=DIR ... and include copies of unchanged files\n");
rprintf(F," --link-dest=DIR hardlink to files in DIR when unchanged\n");
+ rprintf(F," --link-by-hash=DIR create hardlinks by hash into DIR\n");
rprintf(F," -z, --compress compress file data during the transfer\n");
- rprintf(F," -f, --filter=RULE add a file-filtering RULE\n");
-@@ -345,7 +347,7 @@ void usage(enum logcode F)
- enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
- OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST,
- OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
-- OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE,
-+ OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_MAX_SIZE, OPT_LINK_BY_HASH,
- OPT_REFUSED_BASE = 9000};
+@@ -398,7 +400,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OP
+ OPT_FILTER, OPT_COMPARE_DEST, OPT_COPY_DEST, OPT_LINK_DEST, OPT_HELP,
+ OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW, OPT_MIN_SIZE, OPT_CHMOD,
+ OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_ONLY_WRITE_BATCH, OPT_MAX_SIZE,
+- OPT_NO_D,
++ OPT_NO_D, OPT_LINK_BY_HASH,
+ OPT_SERVER, OPT_REFUSED_BASE = 9000};
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
+ {"link-by-hash", 0, POPT_ARG_STRING, 0, OPT_LINK_BY_HASH, 0, 0},
{"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
{"compare-dest", 0, POPT_ARG_STRING, 0, OPT_COMPARE_DEST, 0, 0 },
{"copy-dest", 0, POPT_ARG_STRING, 0, OPT_COPY_DEST, 0, 0 },
{"link-dest", 0, POPT_ARG_STRING, 0, OPT_LINK_DEST, 0, 0 },
+ {"link-by-hash", 0, POPT_ARG_STRING, 0, OPT_LINK_BY_HASH, 0, 0},
{"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
- /* TODO: Should this take an optional int giving the compression level? */
- {"compress", 'z', POPT_ARG_NONE, &do_compression, 0, 0, 0 },
-@@ -834,6 +837,21 @@ int parse_arguments(int *argc, const cha
- basis_dir[basis_dir_cnt++] = (char *)arg;
- break;
+ {"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 },
+ {"compress-level", 0, POPT_ARG_INT, &def_compress_level, 'z', 0, 0 },
+@@ -1089,6 +1092,21 @@ int parse_arguments(int *argc, const cha
+ usage(FINFO);
+ exit_cleanup(0);
-+ arg = sanitize_path(NULL, arg, NULL, 0);
++ arg = sanitize_path(NULL, arg, NULL, 0, NULL);
-@@ -1369,6 +1387,11 @@ void server_options(char **args,int *arg
+@@ -1739,6 +1757,11 @@ void server_options(char **args,int *arg
---- orig/receiver.c 2005-02-14 02:45:10
-+++ receiver.c 2005-01-15 21:29:13
-@@ -35,6 +35,7 @@ extern int preserve_hard_links;
- extern int preserve_perms;
- extern int io_error;
+--- old/receiver.c
++++ new/receiver.c
+@@ -50,6 +50,7 @@ extern int delay_updates;
+ extern struct stats stats;
+ extern char *stdout_format;
extern char *tmpdir;
+extern char *link_by_hash_dir;
extern char *partial_dir;
extern char *basis_dir[];
extern char *tmpdir;
+extern char *link_by_hash_dir;
extern char *partial_dir;
extern char *basis_dir[];
- extern int basis_dir_cnt;
-@@ -137,12 +138,13 @@ static int get_tmpname(char *fnametmp, c
+ extern struct file_list *the_file_list;
+@@ -124,12 +125,13 @@ static int get_tmpname(char *fnametmp, c
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
static int receive_data(int f_in, char *fname_r, int fd_r, OFF_T size_r,
-@@ -162,6 +164,9 @@ static int receive_data(int f_in, char *
+@@ -149,6 +151,9 @@ static int receive_data(int f_in, char *
- while ((i = recv_token(f_in, &data)) != 0) {
-@@ -178,6 +183,8 @@ static int receive_data(int f_in, char *
+ if (append_mode) {
+@@ -191,6 +196,8 @@ static int receive_data(int f_in, char *
-@@ -204,6 +211,8 @@ static int receive_data(int f_in, char *
+@@ -217,6 +224,8 @@ static int receive_data(int f_in, char *
- if (inplace) {
-@@ -244,6 +253,8 @@ static int receive_data(int f_in, char *
+ if (updating_basis) {
+@@ -259,6 +268,8 @@ static int receive_data(int f_in, char *
-@@ -289,7 +300,7 @@ static void read_gen_name(int fd, char *
+@@ -274,7 +285,7 @@ static int receive_data(int f_in, char *
+ receive_data(f_in, NULL, -1, 0, NULL, -1, length, NULL);
}
+ receive_data(f_in, NULL, -1, 0, NULL, -1, length, NULL);
}
-
-@@ -535,8 +546,12 @@ int recv_files(int f_in, struct file_lis
- rprintf(FINFO, "%s\n", safe_fname(fname));
+ static void handle_delayed_updates(struct file_list *flist, char *local_name)
+@@ -611,8 +622,12 @@ int recv_files(int f_in, struct file_lis
+ rprintf(FINFO, "%s\n", fname);
+#endif
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
- fname, fd2, file->length);
+ fname, fd2, file->length, file->u.sum);
+#endif
recv_ok = receive_data(f_in, fnamecmp, fd1, st.st_size,
- fname, fd2, file->length);
+ fname, fd2, file->length, file->u.sum);
---- orig/rsync.c 2005-02-14 02:45:10
-+++ rsync.c 2005-02-07 21:11:30
-@@ -36,6 +36,7 @@ extern int force_delete;
- extern int recurse;
+--- old/rsync.c
++++ new/rsync.c
+@@ -48,6 +48,7 @@ extern int inplace;
-@@ -287,7 +288,12 @@ void finish_transfer(char *fname, char *
- rprintf(FINFO, "renaming %s to %s\n",
- safe_fname(fnametmp), safe_fname(fname));
- }
-- ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
+@@ -271,8 +272,15 @@ void finish_transfer(char *fname, char *
+ /* move tmp file over real file */
+ if (verbose > 2)
+ rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
+- ret = robust_rename(fnametmp, fname, partialptr,
+- file->mode & INITACCESSPERMS);
-+ ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
++ {
++ ret = robust_rename(fnametmp, fname, partialptr,
++ file->mode & INITACCESSPERMS);
++ }
- ret == -2 ? "copy" : "rename",
---- orig/rsync.h 2005-02-14 02:45:10
-+++ rsync.h 2004-07-03 20:20:15
-@@ -605,6 +605,14 @@ struct stats {
+ ret == -2 ? "copy" : "rename",
+--- old/rsync.h
++++ new/rsync.h
+@@ -651,6 +651,14 @@ struct stats {
- #include "lib/mdfour.h"
---- orig/rsync.yo 2005-02-14 02:45:11
-+++ rsync.yo 2005-02-13 06:58:47
-@@ -355,6 +355,7 @@ to the detailed description below for a
+--- old/rsync.yo
++++ new/rsync.yo
+@@ -366,6 +366,7 @@ to the detailed description below for a
--compare-dest=DIR also compare received files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
+ --link-by-hash=DIR create hardlinks by hash into DIR
-z, --compress compress file data during the transfer
--compare-dest=DIR also compare received files relative to DIR
--copy-dest=DIR ... and include copies of unchanged files
--link-dest=DIR hardlink to files in DIR when unchanged
+ --link-by-hash=DIR create hardlinks by hash into DIR
-z, --compress compress file data during the transfer