The patches for 3.0.0pre8.
authorWayne Davison <wayned@samba.org>
Sat, 12 Jan 2008 18:57:10 +0000 (18:57 +0000)
committerWayne Davison <wayned@samba.org>
Sat, 12 Jan 2008 18:57:10 +0000 (18:57 +0000)
20 files changed:
atimes.diff
checksum-updating.diff
checksum-xattr.diff
copy-devices.diff
detect-renamed-lax.diff
detect-renamed.diff
downdate.diff
drop-cache.diff
flags.diff
fsync.diff
link-by-hash.diff
log-checksum.diff
nameconverter.diff [new file with mode: 0644]
omit-dir-changes.diff
openssl-support.diff
preallocate.diff
slp.diff
source-filter_dest-filter.diff
usermap.diff
xattrs.diff

index 1b01c7e..d897f8a 100644 (file)
@@ -143,7 +143,7 @@ diff --git a/generator.c b/generator.c
  #if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
                if (S_ISLNK(file->mode)) {
                        ;
-@@ -923,6 +927,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -921,6 +925,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
                if (link_dest) {
                        if (!hard_link_one(file, fname, cmpbuf, 1))
                                goto try_a_copy;
@@ -152,7 +152,7 @@ diff --git a/generator.c b/generator.c
                        if (preserve_hard_links && F_IS_HLINKED(file))
                                finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
                        if (itemizing && (verbose > 1 || stdout_format_has_i > 1)) {
-@@ -1113,6 +1119,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1111,6 +1117,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
  static void list_file_entry(struct file_struct *f)
  {
        char permbuf[PERMSTRING_SIZE];
@@ -160,7 +160,7 @@ diff --git a/generator.c b/generator.c
        double len;
  
        if (!F_IS_ACTIVE(f)) {
-@@ -1127,14 +1134,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1125,14 +1132,16 @@ static void list_file_entry(struct file_struct *f)
  
  #ifdef SUPPORT_LINKS
        if (preserve_links && S_ISLNK(f->mode)) {
@@ -179,7 +179,7 @@ diff --git a/generator.c b/generator.c
                        f_name(f, NULL));
        }
  }
-@@ -1884,7 +1893,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1882,7 +1891,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
                if (!(file->mode & S_IWUSR))
                        do_chmod(fname, file->mode);
                if (need_retouch_dir_times)
@@ -563,7 +563,7 @@ diff --git a/util.c b/util.c
                t[0].tv_usec = 0;
                t[1].tv_sec = modtime;
                t[1].tv_usec = 0;
-@@ -154,12 +158,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
+@@ -155,12 +159,12 @@ int set_modtime(const char *fname, time_t modtime, mode_t mode)
                return utimes(fname, t);
  #elif defined HAVE_STRUCT_UTIMBUF
                struct utimbuf tbuf;
index 08498f2..653d58a 100644 (file)
@@ -20,7 +20,7 @@ diff --git a/clientserver.c b/clientserver.c
  extern int io_timeout;
  extern int no_detach;
  extern int write_batch;
-@@ -704,6 +705,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -708,6 +709,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
        else if (am_root < 0) /* Treat --fake-super from client as --super. */
                am_root = 2;
  
@@ -539,7 +539,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -237,6 +237,20 @@ locking on this file to ensure that the max connections limit is not
+@@ -241,6 +241,20 @@ locking on this file to ensure that the max connections limit is not
  exceeded for the modules sharing the lock file.
  The default is tt(/var/run/rsyncd.lock).
  
index 7eb2b6a..94953bb 100644 (file)
@@ -178,7 +178,7 @@ diff --git a/xattrs.c b/xattrs.c
  
  typedef struct {
        char *datum, *name;
-@@ -841,6 +845,39 @@ int del_def_xattr_acl(const char *fname)
+@@ -853,6 +857,39 @@ int del_def_xattr_acl(const char *fname)
  }
  #endif
  
index be1a45f..7cb23b0 100644 (file)
@@ -19,7 +19,7 @@ diff --git a/generator.c b/generator.c
  extern int preserve_specials;
  extern int preserve_hard_links;
  extern int preserve_perms;
-@@ -1566,7 +1567,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1564,7 +1565,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
  
index 38f029c..b1007ae 100644 (file)
@@ -34,7 +34,7 @@ diff --git a/generator.c b/generator.c
                diff = u_strcmp(fmid->basename, f->basename);
                if (diff == 0) {
                        good_match = mid;
-@@ -1864,6 +1866,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1862,6 +1864,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                fnamecmp = partialptr;
                fnamecmp_type = FNAMECMP_PARTIAL_DIR;
                statret = 0;
index 6a30631..90f3803 100644 (file)
@@ -452,7 +452,7 @@ diff --git a/generator.c b/generator.c
  
        if (do_progress && !am_server)
                rprintf(FINFO, "                    \r");
-@@ -1139,6 +1290,7 @@ static void list_file_entry(struct file_struct *f)
+@@ -1137,6 +1288,7 @@ static void list_file_entry(struct file_struct *f)
        }
  }
  
@@ -460,7 +460,7 @@ diff --git a/generator.c b/generator.c
  static int phase = 0;
  static int dflt_perms;
  
-@@ -1383,8 +1535,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1381,8 +1533,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        }
                }
                else if (delete_during && f_out != -1 && !phase && dry_run < 2
@@ -475,7 +475,7 @@ diff --git a/generator.c b/generator.c
                goto cleanup;
        }
  
-@@ -1662,8 +1818,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1660,8 +1816,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        goto cleanup;
                }
  #endif
@@ -491,7 +491,7 @@ diff --git a/generator.c b/generator.c
                rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
                        full_fname(fname));
                goto cleanup;
-@@ -2000,6 +2162,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -2004,6 +2166,12 @@ void generate_files(int f_out, const char *local_name)
        if (verbose > 2)
                rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
  
@@ -504,7 +504,7 @@ diff --git a/generator.c b/generator.c
        if (delete_before && !solo_file && cur_flist->used > 0)
                do_delete_pass();
        if (delete_during == 2) {
-@@ -2010,7 +2178,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2014,7 +2182,7 @@ void generate_files(int f_out, const char *local_name)
        }
        do_progress = 0;
  
@@ -513,7 +513,7 @@ diff --git a/generator.c b/generator.c
                whole_file = 0;
        if (verbose >= 2) {
                rprintf(FINFO, "delta-transmission %s\n",
-@@ -2048,7 +2216,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2052,7 +2220,7 @@ void generate_files(int f_out, const char *local_name)
                                                dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
                                        } else
                                                dirdev = MAKEDEV(0, 0);
@@ -522,7 +522,7 @@ diff --git a/generator.c b/generator.c
                                }
                        }
                }
-@@ -2091,7 +2259,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2095,7 +2263,21 @@ void generate_files(int f_out, const char *local_name)
        } while ((cur_flist = cur_flist->next) != NULL);
  
        if (delete_during)
@@ -634,7 +634,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/util.c b/util.c
 --- a/util.c
 +++ b/util.c
-@@ -1022,6 +1022,32 @@ int handle_partial_dir(const char *fname, int create)
+@@ -1019,6 +1019,32 @@ int handle_partial_dir(const char *fname, int create)
        return 1;
  }
  
index 652d460..6fe7bed 100644 (file)
@@ -18,7 +18,7 @@ diff --git a/generator.c b/generator.c
  extern int ignore_existing;
  extern int ignore_non_existing;
  extern int inplace;
-@@ -1603,6 +1604,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1601,6 +1602,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                goto cleanup;
        }
  
@@ -33,21 +33,21 @@ diff --git a/generator.c b/generator.c
        fnamecmp_type = FNAMECMP_FNAME;
  
 @@ -1917,6 +1925,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
-               ignore_existing = -ignore_existing;
-               ignore_non_existing = -ignore_non_existing;
-               update_only = -update_only;
-+              downdate_only = -downdate_only;
-               always_checksum = -always_checksum;
-               size_only = -size_only;
-               append_mode = -append_mode;
+                       ignore_existing = -ignore_existing;
+                       ignore_non_existing = -ignore_non_existing;
+                       update_only = -update_only;
++                      downdate_only = -downdate_only;
+                       always_checksum = -always_checksum;
+                       size_only = -size_only;
+                       append_mode = -append_mode;
 @@ -1942,6 +1951,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
-               ignore_existing = -ignore_existing;
-               ignore_non_existing = -ignore_non_existing;
-               update_only = -update_only;
-+              downdate_only = -downdate_only;
-               always_checksum = -always_checksum;
-               size_only = -size_only;
-               append_mode = -append_mode;
+                       ignore_existing = -ignore_existing;
+                       ignore_non_existing = -ignore_non_existing;
+                       update_only = -update_only;
++                      downdate_only = -downdate_only;
+                       always_checksum = -always_checksum;
+                       size_only = -size_only;
+                       append_mode = -append_mode;
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
index a18bd98..8c282e0 100644 (file)
@@ -104,8 +104,8 @@ diff --git a/configure.in b/configure.in
 -    extattr_get_link sigaction sigprocmask setattrlist)
 +    extattr_get_link sigaction sigprocmask setattrlist posix_fadvise64)
  
- AC_CHECK_FUNCS(getpgrp tcgetpgrp)
- if test $ac_cv_func_getpgrp = yes; then
+ dnl cygwin iconv.h defines iconv_open as libiconv_open
+ if test x"$ac_cv_func_iconv_open" != x"yes"; then
 diff --git a/fileio.c b/fileio.c
 --- a/fileio.c
 +++ b/fileio.c
index 3e3320d..2673e91 100644 (file)
@@ -48,7 +48,7 @@ diff --git a/configure.in b/configure.in
 +    chflags strerror putenv iconv_open locale_charset nl_langinfo getxattr \
      extattr_get_link sigaction sigprocmask setattrlist)
  
- AC_CHECK_FUNCS(getpgrp tcgetpgrp)
+ dnl cygwin iconv.h defines iconv_open as libiconv_open
 diff --git a/flist.c b/flist.c
 --- a/flist.c
 +++ b/flist.c
@@ -263,7 +263,7 @@ diff --git a/generator.c b/generator.c
                }
        }
  
-@@ -1296,7 +1307,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1294,7 +1305,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                         * full later (right before we handle its contents). */
                        if (statret == 0
                         && (S_ISDIR(sx.st.st_mode)
@@ -272,7 +272,7 @@ diff --git a/generator.c b/generator.c
                                goto cleanup; /* Any errors get reported later. */
                        if (do_mkdir(fname, file->mode & 0700) == 0)
                                file->flags |= FLAG_DIR_CREATED;
-@@ -1308,7 +1319,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1306,7 +1317,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                 * we need to delete it.  If it doesn't exist, then
                 * (perhaps recursively) create it. */
                if (statret == 0 && !S_ISDIR(sx.st.st_mode)) {
@@ -281,7 +281,7 @@ diff --git a/generator.c b/generator.c
                                goto skipping_dir_contents;
                        statret = -1;
                }
-@@ -1437,7 +1448,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1435,7 +1446,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                        }
                        /* Not the right symlink (or not a symlink), so
                         * delete it. */
@@ -290,7 +290,7 @@ diff --git a/generator.c b/generator.c
                                goto cleanup;
                } else if (basis_dir[0] != NULL) {
                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
-@@ -1516,7 +1527,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1514,7 +1525,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                                        goto return_with_success;
                                goto cleanup;
                        }
@@ -299,7 +299,7 @@ diff --git a/generator.c b/generator.c
                                goto cleanup;
                } else if (basis_dir[0] != NULL) {
                        int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
-@@ -1607,7 +1618,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1605,7 +1616,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
        fnamecmp_type = FNAMECMP_FNAME;
  
        if (statret == 0 && !S_ISREG(sx.st.st_mode)) {
@@ -477,7 +477,7 @@ diff --git a/rsync.c b/rsync.c
        if (verbose > 1 && flags & ATTRS_REPORT) {
                if (updated)
                        rprintf(FCLIENT, "%s\n", fname);
-@@ -528,6 +583,9 @@ void finish_transfer(const char *fname, const char *fnametmp,
+@@ -530,6 +585,9 @@ int finish_transfer(const char *fname, const char *fnametmp,
        set_file_attrs(fnametmp, file, NULL, fnamecmp,
                       ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
  
@@ -487,14 +487,14 @@ diff --git a/rsync.c b/rsync.c
        /* move tmp file over real file */
        if (verbose > 2)
                rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
-@@ -542,6 +600,9 @@ void finish_transfer(const char *fname, const char *fnametmp,
+@@ -547,6 +605,9 @@ int finish_transfer(const char *fname, const char *fnametmp,
        }
        if (ret == 0) {
                /* The file was moved into place (not copied), so it's done. */
 +#ifdef SUPPORT_FLAGS
 +              undo_make_mutable(fname, file->mode, F_FFLAGS(file));
 +#endif
-               return;
+               return 1;
        }
        /* The file was copied, so tweak the perms of the copied file.  If it
 diff --git a/rsync.h b/rsync.h
index dc856d8..fb8f076 100644 (file)
@@ -90,7 +90,7 @@ diff --git a/util.c b/util.c
  extern int modify_window;
  extern int relative_paths;
  extern int human_readable;
-@@ -314,6 +315,13 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -315,6 +316,13 @@ int copy_file(const char *source, const char *dest, int ofd,
                        full_fname(source));
        }
  
index 7dcea6b..423c9a2 100644 (file)
@@ -540,11 +540,11 @@ diff --git a/rsync.c b/rsync.c
  extern struct file_list *cur_flist, *first_flist, *dir_flist;
  extern struct chmod_mode_struct *daemon_chmod_modes;
  #ifdef ICONV_OPTION
-@@ -531,8 +532,15 @@ void finish_transfer(const char *fname, const char *fnametmp,
+@@ -533,8 +534,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
        /* move tmp file over real file */
        if (verbose > 2)
                rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
--      ret = robust_rename(fnametmp, fname, partialptr,
+-      ret = robust_rename(fnametmp, fname, temp_copy_name,
 -                          file->mode & INITACCESSPERMS);
 +#ifdef HAVE_LINK
 +      if (link_by_hash_dir)
@@ -552,7 +552,7 @@ diff --git a/rsync.c b/rsync.c
 +      else
 +#endif
 +      {
-+              ret = robust_rename(fnametmp, fname, partialptr,
++              ret = robust_rename(fnametmp, fname, temp_copy_name,
 +                                  file->mode & INITACCESSPERMS);
 +      }
        if (ret < 0) {
index c24f568..7dd5f48 100644 (file)
@@ -167,7 +167,7 @@ diff --git a/rsync.yo b/rsync.yo
 diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
 --- a/rsyncd.conf.yo
 +++ b/rsyncd.conf.yo
-@@ -460,7 +460,8 @@ quote(itemization(
+@@ -464,7 +464,8 @@ quote(itemization(
    it() %a the remote IP address
    it() %b the number of bytes actually transferred
    it() %B the permission bits of the file (e.g. rwxrwxrwt)
diff --git a/nameconverter.diff b/nameconverter.diff
new file mode 100644 (file)
index 0000000..2f428c8
--- /dev/null
@@ -0,0 +1,397 @@
+This patch adds a "name converter" daemon option that allows you
+to specify a user-/group- name converter program that converts
+between ID numbers and names.  This only works in daemon mode,
+and is useful for both chroot use (since the converter runs
+outside the chroot) or to specify a converter that doesn't use
+the normal passwd/group setup.
+
+The converter must use a null char ('\0') as the line terminator
+for input/output on stdin/stdout.  A sample converter written in
+perl is supplied in the support dir: nameconvert.  To use it,
+specify this daemon option:
+
+    name converter = /path/nameconvert
+
+If /path/ is omitted, the script will be found on the $PATH.
+
+To use this patch, run these commands for a successful build:
+
+    patch -p1 <patches/nameconverter.diff
+    ./configure                         (optional if already run)
+    make
+
+diff --git a/clientserver.c b/clientserver.c
+--- a/clientserver.c
++++ b/clientserver.c
+@@ -59,6 +59,7 @@ char *auth_user;
+ int read_only = 0;
+ int module_id = -1;
+ int munge_symlinks = 0;
++pid_t namecvt_pid = 0;
+ struct chmod_mode_struct *daemon_chmod_modes;
+ /* module_dirlen is the length of the module_dir string when in daemon
+@@ -67,6 +68,7 @@ char *module_dir = NULL;
+ unsigned int module_dirlen = 0;
+ static int rl_nulls = 0;
++static int namecvt_fd_req = -1, namecvt_fd_ans = -1;
+ #ifdef HAVE_SIGACTION
+ static struct sigaction sigact;
+@@ -508,7 +510,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+       log_init(1);
+ #ifdef HAVE_PUTENV
+-      if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i)) {
++      if (*lp_prexfer_exec(i) || *lp_postxfer_exec(i) || *lp_name_converter(i)) {
+               char *modname, *modpath, *hostaddr, *hostname, *username;
+               int status;
+               if (asprintf(&modname, "RSYNC_MODULE_NAME=%s", name) < 0
+@@ -595,6 +597,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+                       set_blocking(fds[1]);
+                       pre_exec_fd = fds[1];
+               }
++              if (*lp_name_converter(i)) {
++                      int fds_to[2], fds_from[2];
++                      if (pipe(fds_to) < 0 || pipe(fds_from) < 0
++                       || (namecvt_pid = fork()) < 0) {
++                              rsyserr(FLOG, errno, "name-converter exec preparation failed");
++                              io_printf(f_out, "@ERROR: name-converter exec preparation failed\n");
++                              return -1;
++                      }
++                      if (namecvt_pid == 0) {
++                              char *args[100], *run = lp_name_converter(i);
++                              int cnt = 0;
++                              close(fds_to[1]);
++                              close(fds_from[0]);
++                              set_blocking(fds_to[0]);
++                              set_blocking(fds_from[1]);
++                              close(STDIN_FILENO);
++                              close(STDOUT_FILENO);
++                              dup2(fds_to[0], STDIN_FILENO);
++                              dup2(fds_from[1], STDOUT_FILENO);
++                              while (cnt+1 < (int)(sizeof args / sizeof (char *))) {
++                                      char *space = strchr(run, ' ');
++                                      args[cnt++] = run;
++                                      if (!space)
++                                              break;
++                                      *space = '\0';
++                                      run = space + 1;
++                              }
++                              args[cnt] = NULL;
++                              execvp(args[0], args);
++                              _exit(1);
++                      }
++                      close(fds_to[0]);
++                      close(fds_from[1]);
++                      set_blocking(fds_to[1]);
++                      set_blocking(fds_from[0]);
++                      namecvt_fd_req = fds_to[1];
++                      namecvt_fd_ans = fds_from[0];
++              }
+               umask(0);
+       }
+ #endif
+@@ -789,6 +829,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+       return 0;
+ }
++int namecvt_name(const char *cmd, const char *name)
++{
++      char buf[1024];
++      int got, len = snprintf(buf, sizeof buf, "%s %s", cmd, name);
++      if (len >= (int)sizeof buf) {
++              rprintf(FERROR, "namecvt_name() request was too large.\n");
++              exit_cleanup(RERR_UNSUPPORTED);
++      }
++      while ((got = write(namecvt_fd_req, buf, len + 1)) != len + 1) {
++              if (got < 0 && errno == EINTR)
++                      continue;
++              rprintf(FERROR, "Connection to name-converter failed.\n");
++              exit_cleanup(RERR_SOCKETIO);
++      }
++      if (!(len = read_arg_from_pipe(namecvt_fd_ans, buf, sizeof buf)))
++              return 0;
++      return atoi(buf);
++}
++
++const char *namecvt_id(const char *cmd, int id)
++{
++      char buf[1024];
++      int got, len = snprintf(buf, sizeof buf, "%s %d", cmd, id);
++      if (len >= (int)sizeof buf) {
++              rprintf(FERROR, "namecvt_id() request was too large.\n");
++              exit_cleanup(RERR_UNSUPPORTED);
++      }
++      while ((got = write(namecvt_fd_req, buf, len + 1)) != len + 1) {
++              if (got < 0 && errno == EINTR)
++                      continue;
++              rprintf(FERROR, "Connection to name-converter failed.\n");
++              exit_cleanup(RERR_SOCKETIO);
++      }
++      if (!(len = read_arg_from_pipe(namecvt_fd_ans, buf, sizeof buf)))
++              return NULL;
++      return strdup(buf);
++}
++
+ /* send a list of available modules to the client. Don't list those
+    with "list = False". */
+ static void send_listing(int fd)
+diff --git a/loadparm.c b/loadparm.c
+--- a/loadparm.c
++++ b/loadparm.c
+@@ -139,6 +139,7 @@ typedef struct
+       char *log_file;
+       char *log_format;
+       char *name;
++      char *name_converter;
+       char *outgoing_chmod;
+       char *path;
+       char *postxfer_exec;
+@@ -188,6 +189,7 @@ static service sDefault =
+  /* log_file; */              NULL,
+  /* log_format; */            "%o %h [%a] %m (%u) %f %l",
+  /* name; */                  NULL,
++ /* name_converter; */                NULL,
+  /* outgoing_chmod; */                NULL,
+  /* path; */                  NULL,
+  /* postxfer_exec; */         NULL,
+@@ -323,6 +325,7 @@ static struct parm_struct parm_table[] =
+  {"max verbosity",     P_INTEGER,P_LOCAL, &sDefault.max_verbosity,     NULL,0},
+  {"munge symlinks",    P_BOOL,   P_LOCAL, &sDefault.munge_symlinks,    NULL,0},
+  {"name",              P_STRING, P_LOCAL, &sDefault.name,              NULL,0},
++ {"name converter",    P_STRING, P_LOCAL, &sDefault.name_converter,    NULL,0},
+  {"outgoing chmod",    P_STRING, P_LOCAL, &sDefault.outgoing_chmod,    NULL,0},
+  {"path",              P_PATH,   P_LOCAL, &sDefault.path,              NULL,0},
+ #ifdef HAVE_PUTENV
+@@ -411,6 +414,7 @@ FN_LOCAL_STRING(lp_outgoing_chmod, outgoing_chmod)
+ FN_LOCAL_STRING(lp_path, path)
+ FN_LOCAL_STRING(lp_postxfer_exec, postxfer_exec)
+ FN_LOCAL_STRING(lp_prexfer_exec, prexfer_exec)
++FN_LOCAL_STRING(lp_name_converter, name_converter)
+ FN_LOCAL_STRING(lp_refuse_options, refuse_options)
+ FN_LOCAL_STRING(lp_secrets_file, secrets_file)
+ FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
+diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
+--- a/rsyncd.conf.yo
++++ b/rsyncd.conf.yo
+@@ -144,7 +144,10 @@ args if rsync believes they would escape the chroot.
+ The default for "use chroot" is true, and is the safer choice (especially
+ if the module is not read-only).
+-In order to preserve usernames and groupnames, rsync needs to be able to
++In order to preserve usernames and groupnames, you can use the
++bf(name converter) option to specify a name-converting program that the
++rsync daemon will start prior to enabling chroot (see the option for more
++details).  If that option is not specified, the daemon needs to be able to
+ use the standard library functions for looking up names and IDs (i.e.
+ code(getpwuid()), code(getgrgid()), code(getpwname()), and code(getgrnam())).  This means a
+ process in the chroot namespace will need to have access to the resources
+@@ -200,6 +203,27 @@ path elements that rsync believes will allow a symlink to escape the module's
+ hierarchy.  There are tricky ways to work around this, though, so you had
+ better trust your users if you choose this combination of options.
++dit(bf(name converter))  The "name converter" option lets you specify a
++program that will be run by the rsync daemon (prior to bf(use chroot), if
++that option is enabled) to convert user/group names into numbers or visa
++versa.  There is a sample perl script in the support directory named
++"nameconvert" that you can use to enable the use of the normal passwd/group
++lookup calls in a chroot daemon (which does not require any extra files
++be placed in the chroot area).  This use is configured as follows:
++
++verb(    name converter = /path/nameconvert)
++
++You could alternately specify a program that responds to each request using
++a lookup table to find the names and numbers, this allows you to configure
++per-module name conversion.  See the support/nameconvert script for the
++details of what requests can be sent to the program.
++
++The program will have access to some of the environment variables that are
++described in the section on bf(pre-xfer exec): bf(RSYNC_MODULE_NAME),
++bf(RSYNC_MODULE_PATH), bf(RSYNC_HOST_ADDR), bf(RSYNC_HOST_NAME), and
++bf(RSYNC_USER_NAME).  This is useful if you want to customize the
++conversion using a single program invocation.
++
+ dit(bf(max connections)) The "max connections" option allows you to
+ specify the maximum number of simultaneous connections you will allow.
+ Any clients connecting when the maximum has been reached will receive a
+diff --git a/support/nameconvert b/support/nameconvert
+new file mode 100755
+--- /dev/null
++++ b/support/nameconvert
+@@ -0,0 +1,42 @@
++#!/usr/bin/perl -w
++# This implements a simple protocol to do {user,group}-{name,id}
++# conversions.  All input and output consists of simple strings
++# with a terminating null char (or newline for debugging).  If
++# the conversion fails, an empty string is returned.
++#
++# The requests can be:
++#
++# uid ID_NUM\0  ->  NAME\0
++# gid ID_NUM\0  ->  NAME\0
++# usr NAME\0    ->  ID_NUM\0
++# grp NAME\0    ->  ID_NUM\0
++#
++# An unknown ID_NUM or NAME results in an empty return value.
++#
++# This is used by an rsync daemon when configured with the
++# "name converter" setting.
++
++use strict;
++
++my $eol = grep(/^--debug$/, @ARGV) ? "\n" : "\0";
++$/ = $eol;
++
++$| = 1;
++
++while (<STDIN>) {
++    chomp;
++    my $ans;
++    if (/^uid (\d+)$/) {
++      $ans = getpwuid($1);
++    } elsif (/^gid (\d+)$/) {
++      $ans = getgrgid($1);
++    } elsif (/^usr (\S+)$/) {
++      $ans = getpwnam($1);
++    } elsif (/^grp (\S+)$/) {
++      $ans = getgrnam($1);
++    } else {
++      die "Invalid request: $_";
++    }
++    $ans = '' unless defined $ans;
++    print $ans, $eol;
++}
+diff --git a/t_stub.c b/t_stub.c
+--- a/t_stub.c
++++ b/t_stub.c
+@@ -29,6 +29,7 @@ int module_dirlen = 0;
+ mode_t orig_umask = 002;
+ char *partial_dir;
+ char *module_dir;
++pid_t namecvt_pid;
+ struct filter_list_struct server_filter_list;
+  void rprintf(UNUSED(enum logcode code), const char *format, ...)
+@@ -69,6 +70,11 @@ struct filter_list_struct server_filter_list;
+       return -1;
+ }
++ int namecvt_name(UNUSED(const char *cmd), UNUSED(const char *name))
++{
++      return 0;
++}
++
+  char *lp_name(UNUSED(int mod))
+ {
+       return NULL;
+diff --git a/uidlist.c b/uidlist.c
+--- a/uidlist.c
++++ b/uidlist.c
+@@ -32,6 +32,7 @@ extern int preserve_uid;
+ extern int preserve_gid;
+ extern int preserve_acls;
+ extern int numeric_ids;
++extern pid_t namecvt_pid;
+ #ifdef HAVE_GETGROUPS
+ # ifndef GETGROUPS_T
+@@ -69,8 +70,12 @@ static struct idlist *add_to_list(struct idlist **root, id_t id, const char *nam
+ /* turn a uid into a user name */
+ static const char *uid_to_name(uid_t uid)
+ {
+-      struct passwd *pass = getpwuid(uid);
+-      if (pass)
++      struct passwd *pass;
++
++      if (namecvt_pid)
++              return namecvt_id("uid", (int)uid);
++
++      if ((pass = getpwuid(uid)) != NULL)
+               return strdup(pass->pw_name);
+       return NULL;
+ }
+@@ -78,8 +83,12 @@ static const char *uid_to_name(uid_t uid)
+ /* turn a gid into a group name */
+ static const char *gid_to_name(gid_t gid)
+ {
+-      struct group *grp = getgrgid(gid);
+-      if (grp)
++      struct group *grp;
++
++      if (namecvt_pid)
++              return namecvt_id("gid", (int)gid);
++
++      if ((grp = getgrgid(gid)) != NULL)
+               return strdup(grp->gr_name);
+       return NULL;
+ }
+diff --git a/util.c b/util.c
+--- a/util.c
++++ b/util.c
+@@ -30,9 +30,10 @@ extern int modify_window;
+ extern int relative_paths;
+ extern int human_readable;
+ extern char *module_dir;
+-extern unsigned int module_dirlen;
+ extern mode_t orig_umask;
+ extern char *partial_dir;
++extern pid_t namecvt_pid;
++extern unsigned int module_dirlen;
+ extern struct filter_list_struct server_filter_list;
+ int sanitize_paths = 0;
+@@ -468,24 +469,44 @@ void kill_all(int sig)
+ /** Turn a user name into a uid */
+ int name_to_uid(const char *name, uid_t *uid_p)
+ {
+-      struct passwd *pass;
++      uid_t uid;
++
+       if (!name || !*name)
+               return 0;
+-      if (!(pass = getpwnam(name)))
+-              return 0;
+-      *uid_p = pass->pw_uid;
++
++      if (namecvt_pid) {
++              if (!(uid = namecvt_name("usr", name)))
++                      return 0;
++      } else {
++              struct passwd *pass;
++              if (!(pass = getpwnam(name)))
++                      return 0;
++              uid = pass->pw_uid;
++      }
++
++      *uid_p = uid;
+       return 1;
+ }
+ /** Turn a group name into a gid */
+ int name_to_gid(const char *name, gid_t *gid_p)
+ {
+-      struct group *grp;
++      gid_t gid;
++
+       if (!name || !*name)
+               return 0;
+-      if (!(grp = getgrnam(name)))
+-              return 0;
+-      *gid_p = grp->gr_gid;
++
++      if (namecvt_pid) {
++              if (!(gid = namecvt_name("grp", name)))
++                      return 0;
++      } else {
++              struct group *grp;
++              if (!(grp = getgrnam(name)))
++                      return 0;
++              gid = grp->gr_gid;
++      }
++
++      *gid_p = gid;
+       return 1;
+ }
index 58ad0c3..9be94e3 100644 (file)
@@ -41,7 +41,7 @@ diff --git a/generator.c b/generator.c
                        iflags |= ITEM_REPORT_GROUP;
  #ifdef SUPPORT_ACLS
                if (preserve_acls && !S_ISLNK(file->mode)) {
-@@ -1321,7 +1324,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1319,7 +1322,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
                real_sx = sx;
                if (file->flags & FLAG_DIR_CREATED)
                        statret = -1;
index e6b1e13..8dc8924 100644 (file)
@@ -163,7 +163,7 @@ diff --git a/clientserver.c b/clientserver.c
                        return -1;
                }
  
-@@ -835,6 +882,9 @@ int start_daemon(int f_in, int f_out)
+@@ -839,6 +886,9 @@ int start_daemon(int f_in, int f_out)
        if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0)
                return -1;
  
@@ -173,7 +173,7 @@ diff --git a/clientserver.c b/clientserver.c
        line[0] = 0;
        if (!read_line_old(f_in, line, sizeof line))
                return -1;
-@@ -846,6 +896,20 @@ int start_daemon(int f_in, int f_out)
+@@ -850,6 +900,20 @@ int start_daemon(int f_in, int f_out)
                return -1;
        }
  
index f59b856..f5f21a4 100644 (file)
@@ -19,8 +19,8 @@ diff --git a/configure.in b/configure.in
 -    extattr_get_link sigaction sigprocmask setattrlist)
 +    extattr_get_link sigaction sigprocmask setattrlist posix_fallocate)
  
- AC_CHECK_FUNCS(getpgrp tcgetpgrp)
- if test $ac_cv_func_getpgrp = yes; then
+ dnl cygwin iconv.h defines iconv_open as libiconv_open
+ if test x"$ac_cv_func_iconv_open" != x"yes"; then
 diff --git a/options.c b/options.c
 --- a/options.c
 +++ b/options.c
@@ -224,7 +224,7 @@ diff --git a/util.c b/util.c
  extern int module_id;
  extern int modify_window;
  extern int relative_paths;
-@@ -272,6 +273,10 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -273,6 +274,10 @@ int copy_file(const char *source, const char *dest, int ofd,
        int ifd;
        char buf[1024 * 8];
        int len;   /* Number of bytes read into `buf'. */
@@ -235,7 +235,7 @@ diff --git a/util.c b/util.c
  
        if ((ifd = do_open(source, O_RDONLY, 0)) < 0) {
                rsyserr(FERROR_XFER, errno, "open %s", full_fname(source));
-@@ -293,7 +298,27 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -294,7 +299,27 @@ int copy_file(const char *source, const char *dest, int ofd,
                }
        }
  
@@ -263,7 +263,7 @@ diff --git a/util.c b/util.c
                if (full_write(ofd, buf, len) < 0) {
                        rsyserr(FERROR_XFER, errno, "write %s", full_fname(dest));
                        close(ifd);
-@@ -314,6 +339,16 @@ int copy_file(const char *source, const char *dest, int ofd,
+@@ -315,6 +340,16 @@ int copy_file(const char *source, const char *dest, int ofd,
                        full_fname(source));
        }
  
index 276830a..12dd4b6 100644 (file)
--- a/slp.diff
+++ b/slp.diff
@@ -43,7 +43,7 @@ diff --git a/Makefile.in b/Makefile.in
 diff --git a/clientserver.c b/clientserver.c
 --- a/clientserver.c
 +++ b/clientserver.c
-@@ -969,6 +969,13 @@ int daemon_main(void)
+@@ -973,6 +973,13 @@ int daemon_main(void)
         * address too.  In fact, why not just do inet_ntop on the
         * local address??? */
  
@@ -60,7 +60,7 @@ diff --git a/clientserver.c b/clientserver.c
 diff --git a/configure.in b/configure.in
 --- a/configure.in
 +++ b/configure.in
-@@ -632,6 +632,29 @@ if test $rsync_cv_can_hardlink_special = yes; then
+@@ -637,6 +637,29 @@ if test $rsync_cv_can_hardlink_special = yes; then
      AC_DEFINE(CAN_HARDLINK_SPECIAL, 1, [Define to 1 if link() can hard-link special files.])
  fi
  
@@ -235,7 +235,7 @@ diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
  enddit()
  
  
-@@ -603,6 +612,7 @@ use chroot = no
+@@ -607,6 +616,7 @@ use chroot = no
  max connections = 4
  syslog facility = local5
  pid file = /var/run/rsyncd.pid
index a395b51..5a5bf15 100644 (file)
@@ -309,8 +309,8 @@ diff --git a/receiver.c b/receiver.c
 +              }
 +
                if ((recv_ok && (!delay_updates || !partialptr)) || inplace) {
-                       char *temp_copy_name;
                        if (partialptr == fname)
+                               partialptr = NULL;
 diff --git a/rsync.h b/rsync.h
 --- a/rsync.h
 +++ b/rsync.h
index 439a6e1..2b89567 100644 (file)
@@ -188,7 +188,7 @@ diff --git a/uidlist.c b/uidlist.c
 +
  struct idlist {
        struct idlist *next;
-       char *name;
+       const char *name;
 @@ -48,8 +54,8 @@ struct idlist {
        uint16 flags;
  };
@@ -198,9 +198,9 @@ diff --git a/uidlist.c b/uidlist.c
 +static struct idlist *uidlist, *uidmap;
 +static struct idlist *gidlist, *gidmap;
  
- static struct idlist *add_to_list(struct idlist **root, id_t id, char *name,
+ static struct idlist *add_to_list(struct idlist **root, id_t id, const char *name,
                                  id_t id2, uint16 flags)
-@@ -84,22 +90,6 @@ static char *gid_to_name(gid_t gid)
+@@ -84,22 +90,6 @@ static const char *gid_to_name(gid_t gid)
        return NULL;
  }
  
index 72807f0..0768dae 100644 (file)
@@ -46,7 +46,7 @@ diff --git a/xattrs.c b/xattrs.c
  
  #define RSYNC_XAL_INITIAL 5
  #define RSYNC_XAL_LIST_INITIAL 100
-@@ -241,7 +243,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
+@@ -242,7 +244,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
                if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
                        return -1;
  
@@ -55,7 +55,7 @@ diff --git a/xattrs.c b/xattrs.c
                        /* For large datums, we store a flag and a checksum. */
                        name_offset = 1 + MAX_DIGEST_LEN;
                        sum_init(checksum_seed);
-@@ -305,7 +307,7 @@ static int find_matching_xattr(item_list *xalp)
+@@ -310,7 +312,7 @@ static int find_matching_xattr(item_list *xalp)
                         || rxas1[j].datum_len != rxas2[j].datum_len
                         || strcmp(rxas1[j].name, rxas2[j].name))
                                break;
@@ -64,7 +64,7 @@ diff --git a/xattrs.c b/xattrs.c
                                if (memcmp(rxas1[j].datum + 1,
                                           rxas2[j].datum + 1,
                                           MAX_DIGEST_LEN) != 0)
-@@ -342,34 +344,43 @@ int send_xattr(stat_x *sxp, int f)
+@@ -347,34 +349,43 @@ int send_xattr(stat_x *sxp, int f)
  {
        int ndx = find_matching_xattr(sxp->xattr);
  
@@ -118,7 +118,7 @@ diff --git a/xattrs.c b/xattrs.c
                                write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
                        else
                                write_buf(f, rxa->datum, rxa->datum_len);
-@@ -419,7 +430,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
+@@ -424,7 +435,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
                cmp = rec_cnt ? strcmp(snd_rxa->name, rec_rxa->name) : -1;
                if (cmp > 0)
                        same = 0;
@@ -127,19 +127,19 @@ diff --git a/xattrs.c b/xattrs.c
                        same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
                            && memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
                                      MAX_DIGEST_LEN) == 0;
-@@ -462,6 +473,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
-       int j, cnt, prior_req = -1;
+@@ -467,6 +478,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
+       int cnt, prior_req = 0;
        rsync_xa *rxa;
  
 +      if (protocol_version < 30)
 +              return;
 +
        lst += F_XATTR(file);
-       cnt = lst->count;
-       for (rxa = lst->items, j = 0; j < cnt; rxa++, j++) {
-@@ -536,6 +550,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
+       for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
+               if (rxa->datum_len <= MAX_FULL_DATUM)
+@@ -540,6 +554,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
        rsync_xa *rxa;
-       int rel_pos, cnt, got_xattr_data = 0;
+       int rel_pos, cnt, num, got_xattr_data = 0;
  
 +      if (protocol_version < 30)
 +              return 0;
@@ -147,10 +147,10 @@ diff --git a/xattrs.c b/xattrs.c
        if (F_XATTR(file) < 0) {
                rprintf(FERROR, "recv_xattr_request: internal data error!\n");
                exit_cleanup(RERR_STREAMIO);
-@@ -585,7 +602,22 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -596,7 +613,22 @@ void receive_xattr(struct file_struct *file, int f)
  {
        static item_list temp_xattr = EMPTY_ITEM_LIST;
-       int count;
+       int count, num;
 -      int ndx = read_varint(f);
 +      int ndx;
 +
@@ -171,7 +171,7 @@ diff --git a/xattrs.c b/xattrs.c
  
        if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
                rprintf(FERROR, "receive_xattr: xa index %d out of"
-@@ -598,7 +630,7 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -609,7 +641,7 @@ void receive_xattr(struct file_struct *file, int f)
                return;
        }
        
@@ -180,8 +180,8 @@ diff --git a/xattrs.c b/xattrs.c
                (void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
                temp_xattr.count = 0;
        }
-@@ -606,9 +638,10 @@ void receive_xattr(struct file_struct *file, int f)
-       while (count--) {
+@@ -617,9 +649,10 @@ void receive_xattr(struct file_struct *file, int f)
+       for (num = 1; num <= count; num++) {
                char *ptr, *name;
                rsync_xa *rxa;
 -              size_t name_len = read_varint(f);