Fixed fuzz and failed hunks.
[rsync/rsync-patches.git] / link-by-hash.diff
index 6ccebc6..b319873 100644 (file)
@@ -1,44 +1,30 @@
-To: rsync@lists.samba.org
-From: "Jason M. Felice" <jfelice@cronosys.com>
-Subject: [patch] Add `--link-by-hash' option (rev 5).
-Date: Mon, 23 Feb 2004 13:29:08 -0500
+After applying this patch and running configure, you MUST run this
+command before "make":
+
+    make proto
+
+Jason M. Felice writes:
 
 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.
 
-(rev 5)
-* Fixed silly logic error.
-
-(rev 4)
-* Updated for committed robust_rename() patch, other changes in CVS.
-
-(rev 3)
-* Don't link empty files.
-* Roll over to new file when filesystem maximum link count is reached.
-* If link fails for another reason, leave non-linked file there.
-* Depends on rsync-rename.diff
-
-(rev 2)
-* This revision is actually against CVS HEAD (I didn't realize I was working
-  from a stale rsync'd CVS).
-* Apply permissions after linking (permissions were lost if we already had
-  a copy of the file in the link farm).
 
-Patch Summary:
-
-    -1   +1    Makefile.in
-    -0   +351  hashlink.c (new)
-    -1   +22   options.c
-    -0   +6    proto.h
-    -6   +21   receiver.c
-    -2   +8    rsync.c
-    -0   +8    rsync.h
-
---- hashlink.c 1969-12-31 19:00:00.000000000 -0500
-+++ hashlink.c 2004-02-23 10:30:45.000000000 -0500
-@@ -0,0 +1,351 @@
+--- Makefile.in        15 May 2004 00:48:11 -0000      1.101
++++ Makefile.in        6 Jun 2004 21:24:41 -0000
+@@ -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 \
+       fileio.o batch.o clientname.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
+--- /dev/null  1 Jan 1970 00:00:00 -0000
++++ hashlink.c 6 Jun 2004 21:24:41 -0000
+@@ -0,0 +1,342 @@
 +/*
 +   Copyright (C) Cronosys, LLC 2004
 +
@@ -129,8 +115,7 @@ Patch Summary:
 +      /* Build a list of potential candidates and open
 +       * them. */
 +      if ((d = opendir(hashname)) == NULL) {
-+              rprintf(FERROR,"opendir \"%s\": %s\n",
-+                      hashname, strerror(errno));
++              rsyserr(FERROR, errno, "opendir \"%s\"", hashname);
 +              free(hashname);
 +              return NULL;
 +      }
@@ -149,8 +134,7 @@ Patch Summary:
 +              asprintf(&hashfile->name,"%s/%s",hashname,
 +                       di->d_name);
 +              if (do_stat(hashfile->name,&st) == -1) {
-+                      rprintf(FERROR,"%s: %s", hashfile->name,
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "%s: %s", hashfile->name);
 +                      kill_hashfile(hashfile);
 +                      continue;
 +              }
@@ -161,8 +145,7 @@ Patch Summary:
 +              hashfile->nlink = st.st_nlink;
 +              hashfile->fd = open(hashfile->name,O_RDONLY|O_BINARY);
 +              if (hashfile->fd == -1) {
-+                      rprintf(FERROR,"%s: %s\n", hashfile->name,
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "%s", hashfile->name);
 +                      kill_hashfile(hashfile);
 +                      continue;
 +              }
@@ -231,7 +214,7 @@ Patch Summary:
 +      }
 +
 +      if (amt == -1) {
-+              rprintf(FERROR,"%s",strerror(errno));
++              rsyserr(FERROR, errno, "%s");
 +              kill_hashfiles(files);
 +              return NULL;
 +      }
@@ -283,8 +266,7 @@ Patch Summary:
 +              dirname = strdup(hashname);
 +              *strrchr(dirname,'/') = 0;
 +              if (do_mkdir(dirname, 0755) == -1 && errno != EEXIST) {
-+                      rprintf(FERROR, "mkdir %s: %s\n", dirname,
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "mkdir %s", dirname);
 +                      free(hashname);
 +                      free(dirname);
 +                      return robust_rename(fnametmp,fname,0644);
@@ -292,8 +274,7 @@ Patch Summary:
 +              free(dirname);
 +
 +              if (do_mkdir(hashname, 0755) == -1 && errno != EEXIST) {
-+                      rprintf(FERROR, "mkdir %s: %s\n", hashname,
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "mkdir %s", hashname);
 +                      free(hashname);
 +                      return robust_rename(fnametmp,fname,0644);
 +              }
@@ -307,7 +288,7 @@ Patch Summary:
 +              int fd;
 +
 +              if (do_stat(fnametmp,&st) == -1) {
-+                      rprintf(FERROR,"%s: %s\n",fname,strerror(errno));
++                      rsyserr(FERROR, errno, "%s", fname);
 +                      return -1;
 +              }
 +              hashfiles = find_hashfiles(hashname, st.st_size, &last_fnbr);
@@ -320,8 +301,7 @@ Patch Summary:
 +                      
 +                      /* Search for one identical to us. */
 +                      if ((fd = open(fnametmp,O_RDONLY|O_BINARY)) == -1) {
-+                              rprintf(FERROR,"%s: %s\n",fnametmp,
-+                                      strerror(errno));
++                              rsyserr(FERROR, errno, "%s", fnametmp);
 +                              kill_hashfiles(hashfiles);
 +                              return -1;
 +                      }
@@ -355,9 +335,8 @@ Patch Summary:
 +                              rprintf(FINFO, "(5) linkname = %s\n", linkname);
 +                              rprintf(FINFO,"link-by-hash: max link count exceeded, starting new file \"%s\".\n", linkname);
 +                      } else {
-+                              rprintf(FERROR,"link \"%s\" -> %s: %s\n",
-+                                      linkname,full_fname(fname),
-+                                      strerror(errno));
++                              rsyserr(FERROR, errno, "link \"%s\" -> \"%s\"",
++                                      linkname, full_fname(fname));
 +                              robust_unlink(fname);
 +                              rc = robust_rename(fnametmp,fname,0644);
 +                      }
@@ -372,15 +351,13 @@ Patch Summary:
 +
 +              rc = robust_rename(fnametmp,fname,0644);
 +              if (rc != 0) {
-+                      rprintf(FERROR,"rename \"%s\" -> \"%s\": %s\n",
-+                              full_fname(fnametmp),full_fname(fname),
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "rename \"%s\" -> \"%s\"",
++                              full_fname(fnametmp), full_fname(fname));
 +              }
 +              rc = do_link(fname,linkname);
 +              if (rc != 0) {
-+                      rprintf(FERROR,"link \"%s\" -> \"%s\": %s\n",
-+                              full_fname(fname),linkname,
-+                              strerror(errno));
++                      rsyserr(FERROR, errno, "link \"%s\" -> \"%s\"",
++                              full_fname(fname), linkname);
 +              }
 +      }
 +
@@ -390,20 +367,9 @@ Patch Summary:
 +}
 +
 +#endif
---- Makefile.in        2004-02-23 10:22:51.000000000 -0500
-+++ Makefile.in        2004-02-23 10:22:51.000000000 -0500
-@@ -35,7 +35,7 @@
-       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 \
-       fileio.o batch.o clientname.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
---- options.c  2004-02-23 10:22:51.000000000 -0500
-+++ options.c  2004-02-23 10:29:14.000000000 -0500
-@@ -119,6 +119,7 @@
+--- options.c  6 Jun 2004 19:02:40 -0000       1.155
++++ options.c  6 Jun 2004 21:24:41 -0000
+@@ -124,6 +124,7 @@ char *log_format = NULL;
  char *password_file = NULL;
  char *rsync_path = RSYNC_PATH;
  char *backup_dir = NULL;
@@ -411,7 +377,7 @@ Patch Summary:
  char backup_dir_buf[MAXPATHLEN];
  int rsync_port = RSYNC_PORT;
  int link_dest = 0;
-@@ -264,6 +265,7 @@
+@@ -270,6 +271,7 @@ void usage(enum logcode F)
    rprintf(F," -T  --temp-dir=DIR          create temporary files in directory DIR\n");
    rprintf(F,"     --compare-dest=DIR      also compare destination files relative to DIR\n");
    rprintf(F,"     --link-dest=DIR         create hardlinks to DIR for unchanged files\n");
@@ -419,24 +385,24 @@ Patch Summary:
    rprintf(F," -P                          equivalent to --partial --progress\n");
    rprintf(F," -z, --compress              compress file data\n");
    rprintf(F," -C, --cvs-exclude           auto ignore files in the same way CVS does\n");
-@@ -303,7 +305,7 @@
+@@ -310,7 +312,7 @@ void usage(enum logcode F)
  enum {OPT_VERSION = 1000, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
        OPT_DELETE_AFTER, OPT_DELETE_EXCLUDED, OPT_LINK_DEST,
        OPT_INCLUDE, OPT_INCLUDE_FROM, OPT_MODIFY_WINDOW,
--      OPT_READ_BATCH, OPT_WRITE_BATCH,
-+      OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_LINK_BY_HASH,
+-      OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT,
++      OPT_READ_BATCH, OPT_WRITE_BATCH, OPT_TIMEOUT, OPT_LINK_BY_HASH,
        OPT_REFUSED_BASE = 9000};
  
  static struct poptOption long_options[] = {
-@@ -360,6 +362,7 @@
+@@ -368,6 +370,7 @@ static struct poptOption long_options[] 
    {"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 },
+   {"link-dest",        0,  POPT_ARG_STRING, &compare_dest,  OPT_LINK_DEST, 0, 0 },
 +  {"link-by-hash",     0,  POPT_ARG_STRING, 0,              OPT_LINK_BY_HASH, 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,   &daemon_opt, 0, 0, 0 },
-@@ -577,6 +580,19 @@
+@@ -601,6 +604,19 @@ int parse_arguments(int *argc, const cha
                        return 0;
  #endif
  
@@ -456,7 +422,7 @@ Patch Summary:
                default:
                        /* A large opt value means that set_refuse_options()
                         * turned this option off (opt-BASE is its index). */
-@@ -934,6 +950,11 @@
+@@ -982,6 +998,11 @@ void server_options(char **args,int *arg
                args[ac++] = compare_dest;
        }
  
@@ -468,24 +434,17 @@ Patch Summary:
        if (files_from && (!am_sender || remote_filesfrom_file)) {
                if (remote_filesfrom_file) {
                        args[ac++] = "--files-from";
---- proto.h    2004-02-23 10:22:51.000000000 -0500
-+++ proto.h    2004-02-23 11:06:03.000000000 -0500
-@@ -93,6 +93,12 @@
- void write_sum_head(int f, struct sum_struct *sum);
- void recv_generator(char *fname, struct file_struct *file, int i, int f_out);
- void generate_files(int f, struct file_list *flist, char *local_name);
-+char* make_hash_name(struct file_struct *file);
-+void kill_hashfile(struct hashfile_struct *hashfile);
-+void kill_hashfiles(struct hashfile_struct *hashfiles);
-+struct hashfile_struct *find_hashfiles(char *hashname, int64 size, long *fnbr);
-+struct hashfile_struct *compare_hashfiles(int fd,struct hashfile_struct *files);
-+int link_by_hash(char *fnametmp,char *fname,struct file_struct *file);
- void init_hard_links(struct file_list *flist);
- int hard_link_check(struct file_struct *file, int skip);
- void do_hard_links(void);
---- receiver.c 2004-02-23 10:22:51.000000000 -0500
-+++ receiver.c 2004-02-23 10:22:51.000000000 -0500
-@@ -186,10 +186,11 @@
+--- receiver.c 21 May 2004 08:27:04 -0000      1.79
++++ receiver.c 6 Jun 2004 21:24:41 -0000
+@@ -47,6 +47,7 @@ extern int ignore_errors;
+ extern int orig_umask;
+ extern int keep_partial;
+ extern int checksum_seed;
++extern char *link_by_hash_dir;
+ static void delete_one(char *fn, int is_dir)
+ {
+@@ -193,10 +194,11 @@ static int get_tmpname(char *fnametmp, c
  
  
  static int receive_data(int f_in,struct map_struct *mapbuf,int fd,char *fname,
@@ -498,18 +457,17 @@ Patch Summary:
        unsigned int len;
        OFF_T offset = 0;
        OFF_T offset2;
-@@ -199,7 +200,9 @@
-       char *map=NULL;
+@@ -207,6 +209,9 @@ static int receive_data(int f_in,struct 
  
        read_sum_head(f_in, &sum);
--
 +      if (md4)
 +              mdfour_begin(&mdfour_data);
-+      
-       sum_init();
++
+       sum_init(checksum_seed);
  
        while ((i = recv_token(f_in, &data)) != 0) {
-@@ -216,6 +219,8 @@
+@@ -223,6 +228,8 @@ static int receive_data(int f_in,struct 
                        cleanup_got_literal = 1;
  
                        sum_update(data,i);
@@ -517,8 +475,8 @@ Patch Summary:
 +                              mdfour_update(&mdfour_data,data,i);
  
                        if (fd != -1 && write_file(fd,data,i) != i) {
-                               rprintf(FERROR, "write failed on %s: %s\n",
-@@ -243,6 +248,8 @@
+                               rsyserr(FERROR, errno, "write failed on %s",
+@@ -250,6 +257,8 @@ static int receive_data(int f_in,struct 
  
                        see_token(map, len);
                        sum_update(map,len);
@@ -527,7 +485,7 @@ Patch Summary:
                }
  
                if (fd != -1 && write_file(fd,map,len) != (int) len) {
-@@ -265,6 +272,8 @@
+@@ -272,6 +281,8 @@ static int receive_data(int f_in,struct 
        }
  
        sum_end(file_sum1);
@@ -536,24 +494,16 @@ Patch Summary:
  
        read_buf(f_in,file_sum2,MD4_SUM_LENGTH);
        if (verbose > 2) {
-@@ -299,6 +308,7 @@
-       extern int preserve_perms;
-       extern int delete_after;
-       extern int orig_umask;
-+      extern char *link_by_hash_dir;
-       struct stats initial_stats;
-       if (verbose > 2) {
-@@ -372,7 +382,7 @@
+@@ -375,7 +386,7 @@ int recv_files(int f_in,struct file_list
                if (fd1 != -1 && do_fstat(fd1,&st) != 0) {
-                       rprintf(FERROR, "fstat %s failed: %s\n",
-                               full_fname(fnamecmp), strerror(errno));
+                       rsyserr(FERROR, errno, "fstat %s failed",
+                               full_fname(fnamecmp));
 -                      receive_data(f_in,NULL,-1,NULL,file->length);
 +                      receive_data(f_in,NULL,-1,NULL,file->length,NULL);
                        close(fd1);
                        continue;
                }
-@@ -385,7 +395,7 @@
+@@ -388,7 +399,7 @@ int recv_files(int f_in,struct file_list
                         */
                        rprintf(FERROR,"recv_files: %s is a directory\n",
                                full_fname(fnamecmp));
@@ -562,40 +512,39 @@ Patch Summary:
                        close(fd1);
                        continue;
                }
-@@ -437,7 +447,7 @@
+@@ -440,7 +451,7 @@ int recv_files(int f_in,struct file_list
                if (fd2 == -1) {
-                       rprintf(FERROR, "mkstemp %s failed: %s\n",
-                               full_fname(fnametmp), strerror(errno));
+                       rsyserr(FERROR, errno, "mkstemp %s failed",
+                               full_fname(fnametmp));
 -                      receive_data(f_in,mapbuf,-1,NULL,file->length);
 +                      receive_data(f_in,mapbuf,-1,NULL,file->length,NULL);
                        if (mapbuf) unmap_file(mapbuf);
                        if (fd1 != -1) close(fd1);
                        continue;
-@@ -450,7 +460,12 @@
+@@ -453,7 +464,11 @@ int recv_files(int f_in,struct file_list
                }
  
                /* recv file data */
 -              recv_ok = receive_data(f_in,mapbuf,fd2,fname,file->length);
 +#ifdef HAVE_LINK
-+              if (link_by_hash_dir) {
-+                      file->u.sum = (char*)malloc (MD4_SUM_LENGTH);
-+              }
++              if (link_by_hash_dir)
++                      file->u.sum = (char*)malloc(MD4_SUM_LENGTH);
 +#endif
 +              recv_ok = receive_data(f_in,mapbuf,fd2,fname,file->length,file->u.sum);
  
                log_recv(file, &initial_stats);
  
---- rsync.c    2004-02-23 10:22:51.000000000 -0500
-+++ rsync.c    2004-02-23 12:49:33.000000000 -0500
-@@ -33,6 +33,7 @@
- extern int preserve_gid;
- extern int preserve_perms;
+--- rsync.c    21 May 2004 08:43:03 -0000      1.140
++++ rsync.c    6 Jun 2004 21:24:41 -0000
+@@ -34,6 +34,7 @@ extern int force_delete;
+ extern int recurse;
  extern int make_backups;
+ extern char *backup_dir;
 +extern char *link_by_hash_dir;
  
  
  /*
-@@ -236,8 +237,13 @@
+@@ -239,8 +240,12 @@ void finish_transfer(char *fname, char *
        if (make_backups && !make_backup(fname))
                return;
  
@@ -603,17 +552,16 @@ Patch Summary:
 -      ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
 +#ifdef HAVE_LINK
 +      if (link_by_hash_dir)
-+              ret = link_by_hash(fnametmp,fname,file);
++              ret = link_by_hash(fnametmp, fname, file);
 +      else
 +#endif
 +              ret = robust_rename(fnametmp, fname, file->mode & INITACCESSPERMS);
-+
-       if (ret != 0) {
-               rprintf(FERROR, "%s %s -> \"%s\": %s\n",
+       if (ret < 0) {
+               rsyserr(FERROR, errno, "%s %s -> \"%s\"",
                    ret == -2 ? "copy" : "rename",
---- rsync.h    2004-02-23 10:22:51.000000000 -0500
-+++ rsync.h    2004-02-23 12:42:59.000000000 -0500
-@@ -513,6 +513,14 @@
+--- rsync.h    16 May 2004 07:28:24 -0000      1.204
++++ rsync.h    6 Jun 2004 21:24:41 -0000
+@@ -522,6 +522,14 @@ struct stats {
        int current_file_index;
  };