diff --git a/tls.c b/tls.c
--- a/tls.c
+++ b/tls.c
-@@ -105,6 +105,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
+@@ -107,6 +107,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
#endif
static void failed(char const *what, char const *where)
{
fprintf(stderr, PROGRAM ": %s %s: %s\n",
-@@ -112,12 +114,29 @@ static void failed(char const *what, char const *where)
+@@ -114,12 +116,29 @@ static void failed(char const *what, char const *where)
exit(1);
}
char linkbuf[4096];
if (do_lstat(fname, &buf) < 0)
-@@ -154,19 +173,11 @@ static void list_file(const char *fname)
+@@ -158,19 +177,11 @@ static void list_file(const char *fname)
permstring(permbuf, buf.st_mode);
/* TODO: Perhaps escape special characters in fname? */
-@@ -177,13 +188,14 @@ static void list_file(const char *fname)
+@@ -181,13 +192,14 @@ static void list_file(const char *fname)
(long)minor(buf.st_rdev));
} else /* NB: use double for size since it might not fit in a long. */
printf("%12.0f", (double)buf.st_size);
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
+ {"atimes", 'U', POPT_ARG_NONE, &display_atimes, 0, 0, 0},
+ {"link-times", 'l', POPT_ARG_NONE, &link_times, 0, 0, 0 },
+ {"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 },
#ifdef SUPPORT_XATTRS
- {"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 },
- #endif
-@@ -197,6 +209,7 @@ static void tls_usage(int ret)
+@@ -203,6 +215,7 @@ static void tls_usage(int ret)
fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n");
fprintf(F,"Trivial file listing program for portably checking rsync\n");
fprintf(F,"\nOptions:\n");
+ fprintf(F," -U, --atimes display access (last-used) times\n");
+ fprintf(F," -l, --link-times display the time on a symlink\n");
+ fprintf(F," -L, --link-owner display the owner+group on a symlink\n");
#ifdef SUPPORT_XATTRS
- fprintf(F," -f, --fake-super display attributes including fake-super xattrs\n");
- #endif
diff --git a/util.c b/util.c
--- a/util.c
+++ b/util.c
}
/* This function gets called from all 3 processes. We want the client side
-@@ -1306,6 +1309,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
+@@ -1314,6 +1317,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
break;
}
}
}
#endif
#ifndef HAVE_SIGACTION
-@@ -1364,6 +1375,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
+@@ -1372,6 +1383,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
}
#endif
int main(int argc,char *argv[])
{
-@@ -1386,6 +1403,11 @@ int main(int argc,char *argv[])
+@@ -1394,6 +1411,11 @@ int main(int argc,char *argv[])
SIGACTMASK(SIGFPE, rsync_panic_handler);
SIGACTMASK(SIGABRT, rsync_panic_handler);
SIGACTMASK(SIGBUS, rsync_panic_handler);
diff --git a/socket.c b/socket.c
--- a/socket.c
+++ b/socket.c
-@@ -512,7 +512,17 @@ int is_a_socket(int fd)
+@@ -518,7 +518,17 @@ int is_a_socket(int fd)
static RETSIGTYPE sigchld_handler(UNUSED(int val))
{
#ifdef WNOHANG
extern int io_timeout;
extern int no_detach;
extern int write_batch;
-@@ -782,6 +784,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -780,6 +782,9 @@ 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;
diff --git a/hlink.c b/hlink.c
--- a/hlink.c
+++ b/hlink.c
-@@ -384,7 +384,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
+@@ -385,7 +385,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
break;
}
exceeded for the modules sharing the lock file.
The default is tt(/var/run/rsyncd.lock).
-+dit(bf(checksum files)) This option tells rsync to make use of any cached
++dit(bf(checksum files)) This parameter tells rsync to make use of any cached
+checksum information it finds in per-directory .rsyncsums files when the
+current transfer is using the bf(--checksum) option. The value can be set
+to either "lax", "strict", or "none" -- see the client's bf(--sumfiles)
+config option tells it to. See also the bf(exclude) directive for a way
+to hide the .rsyncsums files from the user.
+
- dit(bf(read only)) The "read only" option determines whether clients
+ dit(bf(read only)) This parameter determines whether clients
will be able to upload files or not. If "read only" is true then any
attempted uploads will fail. If "read only" is false then uploads will
diff --git a/support/rsyncsums b/support/rsyncsums
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
@@ -284,13 +284,15 @@ The default is tt(/var/run/rsyncd.lock).
- dit(bf(checksum files)) This option tells rsync to make use of any cached
+ dit(bf(checksum files)) This parameter tells rsync to make use of any cached
checksum information it finds in per-directory .rsyncsums files when the
current transfer is using the bf(--checksum) option. The value can be set
-to either "lax", "strict", or "none" -- see the client's bf(--sumfiles)
+the bf(exclude) directive for a way to hide the .rsyncsums files from the
+user.
- dit(bf(read only)) The "read only" option determines whether clients
+ dit(bf(read only)) This parameter determines whether clients
will be able to upload files or not. If "read only" is true then any
typedef struct {
char *datum, *name;
-@@ -237,7 +243,9 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
+@@ -238,7 +244,9 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
|| (am_root < 0
&& (strcmp(name+RPRE_LEN+1, XSTAT_SUFFIX) == 0
|| strcmp(name+RPRE_LEN+1, XACC_ACL_SUFFIX) == 0
diff --git a/tls.c b/tls.c
--- a/tls.c
+++ b/tls.c
-@@ -105,6 +105,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
+@@ -107,6 +107,8 @@ static int stat_xattr(const char *fname, STRUCT_STAT *fst)
#endif
static void failed(char const *what, char const *where)
{
fprintf(stderr, PROGRAM ": %s %s: %s\n",
-@@ -112,16 +114,36 @@ static void failed(char const *what, char const *where)
+@@ -114,16 +116,36 @@ static void failed(char const *what, char const *where)
exit(1);
}
#ifdef SUPPORT_XATTRS
if (am_root < 0)
stat_xattr(fname, &buf);
-@@ -154,19 +176,11 @@ static void list_file(const char *fname)
+@@ -158,19 +180,11 @@ static void list_file(const char *fname)
permstring(permbuf, buf.st_mode);
/* TODO: Perhaps escape special characters in fname? */
-@@ -177,13 +191,14 @@ static void list_file(const char *fname)
+@@ -181,13 +195,14 @@ static void list_file(const char *fname)
(long)minor(buf.st_rdev));
} else /* NB: use double for size since it might not fit in a long. */
printf("%12.0f", (double)buf.st_size);
static struct poptOption long_options[] = {
/* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
+ {"crtimes", 'N', POPT_ARG_NONE, &display_crtimes, 0, 0, 0},
+ {"link-times", 'l', POPT_ARG_NONE, &link_times, 0, 0, 0 },
+ {"link-owner", 'L', POPT_ARG_NONE, &link_owner, 0, 0, 0 },
#ifdef SUPPORT_XATTRS
- {"fake-super", 'f', POPT_ARG_VAL, &am_root, -1, 0, 0 },
- #endif
-@@ -197,6 +212,7 @@ static void tls_usage(int ret)
+@@ -203,6 +218,7 @@ static void tls_usage(int ret)
fprintf(F,"usage: " PROGRAM " [OPTIONS] FILE ...\n");
fprintf(F,"Trivial file listing program for portably checking rsync\n");
fprintf(F,"\nOptions:\n");
+ fprintf(F," -N, --crtimes display create times (newness)\n");
+ fprintf(F," -l, --link-times display the time on a symlink\n");
+ fprintf(F," -L, --link-owner display the owner+group on a symlink\n");
#ifdef SUPPORT_XATTRS
- fprintf(F," -f, --fake-super display attributes including fake-super xattrs\n");
- #endif
extern int keep_partial;
extern int got_xfer_error;
+extern int use_db;
+ extern int progress_is_active;
extern char *partial_dir;
extern char *logfile_name;
-
-@@ -124,6 +125,12 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
+@@ -128,6 +129,12 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
/* FALLTHROUGH */
#include "case_N.h"
extern char *bind_address;
extern char *sockopts;
extern char *config_file;
-@@ -554,6 +557,9 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -552,6 +555,9 @@ 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)) {
char *modname, *modpath, *hostaddr, *hostname, *username;
-@@ -770,6 +776,10 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -768,6 +774,10 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
am_server = 1; /* Don't let someone try to be tricky. */
quiet = 0;
extern char *shell_cmd;
extern char *batch_name;
extern char *password_file;
-@@ -1482,6 +1484,9 @@ int main(int argc,char *argv[])
+@@ -1490,6 +1492,9 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
+
+See the bf(--db=CONFIG_FILE) option for full details.
+
- dit(bf(max verbosity)) The "max verbosity" option allows you to control
+ dit(bf(max verbosity)) This parameter allows you to control
the maximum amount of verbose information that you'll allow the daemon to
generate (since the information goes into the log file). The default is 1,
diff --git a/support/rsyncdb b/support/rsyncdb
diff --git a/cleanup.c b/cleanup.c
--- a/cleanup.c
+++ b/cleanup.c
-@@ -46,7 +46,13 @@ void close_all(void)
+@@ -47,7 +47,13 @@ void close_all(void)
int fd;
int ret;
STRUCT_STAT st;
diff --git a/xattrs.c b/xattrs.c
--- a/xattrs.c
+++ b/xattrs.c
-@@ -280,6 +280,10 @@ int get_xattr(const char *fname, stat_x *sxp)
+@@ -281,6 +281,10 @@ int get_xattr(const char *fname, stat_x *sxp)
{
sxp->xattr = new(item_list);
*sxp->xattr = empty_xattr;
#ifdef HAVE_SIGACTION
static struct sigaction sigact;
-@@ -555,7 +557,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -553,7 +555,7 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
log_init(1);
#ifdef HAVE_PUTENV
char *modname, *modpath, *hostaddr, *hostname, *username;
int status;
-@@ -651,6 +653,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -649,6 +651,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];
}
umask(0);
}
#endif
-@@ -880,6 +920,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -878,6 +918,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
return 0;
}
+++ b/rsyncd.conf.yo
@@ -160,10 +160,11 @@ if the module is not read-only).
- When this option is enabled, rsync will not attempt to map users and groups
+ When this parameter is enabled, rsync will not attempt to map users and groups
by name (by default), but instead copy IDs as though bf(--numeric-ids) had
-been specified. In order to enable name-mapping, rsync needs to be able to
+been specified. In order to enable name-mapping, rsync needs either the
/etc/group, but perhaps additional dynamic libraries as well).
@@ -227,6 +228,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.
+ better trust your users if you choose this combination of parameters.
-+dit(bf(name converter)) The "name converter" option lets you specify a
++dit(bf(name converter)) This parameter 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
++that parameter 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
+#endif
extern int keep_partial;
extern int got_xfer_error;
- extern char *partial_dir;
-@@ -121,6 +124,14 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
+ extern int progress_is_active;
+@@ -125,6 +128,14 @@ NORETURN void _exit_cleanup(int code, const char *file, int line)
code, file, line);
}
extern int rsync_port;
extern int protect_args;
extern int ignore_errors;
-@@ -128,8 +131,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
+@@ -126,8 +129,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
#endif
ret = start_inband_exchange(fd, fd, user, remote_argc, remote_argv);
}
static int exchange_protocols(int f_in, int f_out, char *buf, size_t bufsiz, int am_client)
-@@ -272,6 +285,32 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -270,6 +283,32 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
if (verbose > 1)
print_child_argv("sending daemon args:", sargs);
io_printf(f_out, "%.*s\n", modlen, modname);
/* Old servers may just drop the connection here,
-@@ -297,6 +336,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -295,6 +334,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
* server to terminate the listing of modules.
* We don't want to go on and transfer
* anything; just exit. */
exit(0);
}
-@@ -304,6 +347,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -302,6 +345,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
rprintf(FERROR, "%s\n", line);
/* This is always fatal; the server will now
* close the socket. */
return -1;
}
-@@ -941,6 +988,9 @@ int start_daemon(int f_in, int f_out)
+@@ -935,6 +982,9 @@ int start_daemon(int f_in, int f_out)
if (exchange_protocols(f_in, f_out, line, sizeof line, 0) < 0)
return -1;
line[0] = 0;
if (!read_line_old(f_in, line, sizeof line))
return -1;
-@@ -952,6 +1002,20 @@ int start_daemon(int f_in, int f_out)
+@@ -946,6 +996,20 @@ int start_daemon(int f_in, int f_out)
return -1;
}
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -1068,6 +1068,13 @@ int daemon_main(void)
+@@ -1062,6 +1062,13 @@ int daemon_main(void)
* address too. In fact, why not just do inet_ntop on the
* local address??? */
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
-@@ -1112,6 +1112,18 @@ static int start_client(int argc, char *argv[])
+@@ -1120,6 +1120,18 @@ static int start_client(int argc, char *argv[])
if (!read_batch) { /* for read_batch, NO source is specified */
char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
special socket options are set. These settings are superseded by the
bf(--sockopts) command-line option.
-+dit(bf(slp refresh)) This option is used to determine how long service
++dit(bf(slp refresh)) This parameter is used to determine how long service
+advertisements are valid (measured in seconds), and is only applicable if
-+you have Service Location Protocol support compiled in. If this option is
++you have Service Location Protocol support compiled in. If this is
+not set or is set to zero, then service advertisements never time out. If
+this is set to less than 120 seconds, then 120 seconds is used. If it is
+set to more than 65535, then 65535 is used (which is a limitation of SLP).
diff --git a/socket.c b/socket.c
--- a/socket.c
+++ b/socket.c
-@@ -524,6 +524,16 @@ void start_accept_loop(int port, int (*fn)(int, int))
+@@ -530,6 +530,16 @@ void start_accept_loop(int port, int (*fn)(int, int))
{
fd_set deffds;
int *sp, maxfd, i;
#ifdef HAVE_SIGACTION
sigact.sa_flags = SA_NOCLDSTOP;
-@@ -552,14 +562,25 @@ void start_accept_loop(int port, int (*fn)(int, int))
+@@ -558,14 +568,25 @@ void start_accept_loop(int port, int (*fn)(int, int))
maxfd = sp[i];
}
/* close log file before the potentially very long select so
* file can be trimmed by another process instead of growing
-@@ -571,8 +592,18 @@ void start_accept_loop(int port, int (*fn)(int, int))
+@@ -577,8 +598,18 @@ void start_accept_loop(int port, int (*fn)(int, int))
#else
fds = deffds;
#endif
#define RSYNC_XAL_INITIAL 5
#define RSYNC_XAL_LIST_INITIAL 100
-@@ -245,7 +247,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
+@@ -246,7 +248,7 @@ static int rsync_xal_get(const char *fname, item_list *xalp)
if (!(ptr = get_xattr_data(fname, name, &datum_len, 0)))
return -1;
/* 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)
+@@ -306,7 +308,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;
if (memcmp(rxas1[j].datum + 1,
rxas2[j].datum + 1,
MAX_DIGEST_LEN) != 0)
-@@ -342,13 +344,22 @@ int send_xattr(stat_x *sxp, int f)
+@@ -343,13 +345,22 @@ int send_xattr(stat_x *sxp, int f)
{
int ndx = find_matching_xattr(sxp->xattr);
for (rxa = sxp->xattr->items; count--; rxa++) {
size_t name_len = rxa->name_len;
const char *name = rxa->name;
-@@ -367,8 +378,8 @@ int send_xattr(stat_x *sxp, int f)
+@@ -368,8 +379,8 @@ int send_xattr(stat_x *sxp, int f)
name_len += UPRE_LEN;
}
#endif
#ifndef HAVE_LINUX_XATTRS
if (name_len > rxa->name_len) {
write_buf(f, USER_PREFIX, UPRE_LEN);
-@@ -376,7 +387,7 @@ int send_xattr(stat_x *sxp, int f)
+@@ -377,7 +388,7 @@ int send_xattr(stat_x *sxp, int f)
}
#endif
write_buf(f, name, name_len);
write_buf(f, rxa->datum + 1, MAX_DIGEST_LEN);
else
write_buf(f, rxa->datum, rxa->datum_len);
-@@ -426,7 +437,7 @@ int xattr_diff(struct file_struct *file, stat_x *sxp, int find_all)
+@@ -427,7 +438,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;
same = cmp == 0 && snd_rxa->datum_len == rec_rxa->datum_len
&& memcmp(snd_rxa->datum + 1, rec_rxa->datum + 1,
MAX_DIGEST_LEN) == 0;
-@@ -469,6 +480,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
+@@ -470,6 +481,9 @@ void send_xattr_request(const char *fname, struct file_struct *file, int f_out)
int cnt, prior_req = 0;
rsync_xa *rxa;
lst += F_XATTR(file);
for (rxa = lst->items, cnt = lst->count; cnt--; rxa++) {
if (rxa->datum_len <= MAX_FULL_DATUM)
-@@ -523,6 +537,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
+@@ -524,6 +538,9 @@ int recv_xattr_request(struct file_struct *file, int f_in)
rsync_xa *rxa;
int rel_pos, cnt, num, got_xattr_data = 0;
if (F_XATTR(file) < 0) {
rprintf(FERROR, "recv_xattr_request: internal data error!\n");
exit_cleanup(RERR_STREAMIO);
-@@ -584,7 +601,22 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -585,7 +602,22 @@ void receive_xattr(struct file_struct *file, int f)
#else
int need_sort = 1;
#endif
if (ndx < 0 || (size_t)ndx > rsync_xal_l.count) {
rprintf(FERROR, "receive_xattr: xa index %d out of"
-@@ -597,7 +629,7 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -598,7 +630,7 @@ void receive_xattr(struct file_struct *file, int f)
return;
}
(void)EXPAND_ITEM_LIST(&temp_xattr, rsync_xa, count);
temp_xattr.count = 0;
}
-@@ -605,9 +637,10 @@ void receive_xattr(struct file_struct *file, int f)
+@@ -606,9 +638,10 @@ void receive_xattr(struct file_struct *file, int f)
for (num = 1; num <= count; num++) {
char *ptr, *name;
rsync_xa *rxa;
+ size_t dget_len = datum_len > MAX_FULL_DATUM && protocol_version >= 30
+ ? 1 + MAX_DIGEST_LEN : datum_len;
size_t extra_len = MIGHT_NEED_RPRE ? RPRE_LEN : 0;
- if (dget_len + extra_len < dget_len)
- out_of_memory("receive_xattr"); /* overflow */
+ if ((dget_len + extra_len < dget_len)
+ || (dget_len + extra_len + name_len < dget_len))