diff --git a/compat.c b/compat.c
--- a/compat.c
+++ b/compat.c
-@@ -177,13 +177,6 @@ void setup_protocol(int f_out,int f_in)
+@@ -187,13 +187,6 @@ void setup_protocol(int f_out,int f_in)
if (protocol_version < 30) {
if (append_mode == 1)
append_mode = 2;
-int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
+int uid_ndx, gid_ndx, atimes_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
- #ifdef ICONV_OPTION
- int filesfrom_convert = 0;
-@@ -124,6 +125,8 @@ void setup_protocol(int f_out,int f_in)
+ int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
+
+@@ -134,6 +135,8 @@ void setup_protocol(int f_out,int f_in)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
gid_ndx = ++file_extra_cnt;
extern int verbose;
extern int dry_run;
-@@ -605,6 +606,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -613,6 +614,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -958,6 +962,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -967,6 +971,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;
+ set_file_attrs(fname, file, sxp, NULL, 0);
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)) {
-@@ -1144,6 +1150,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+ if (!maybe_ATTRS_REPORT && (verbose > 1 || stdout_format_has_i > 1)) {
+@@ -1153,6 +1159,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];
double len;
if (!F_IS_ACTIVE(f)) {
-@@ -1158,14 +1165,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1167,14 +1174,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -1916,7 +1925,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -1929,7 +1938,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)
diff --git a/log.c b/log.c
--- a/log.c
+++ b/log.c
-@@ -642,7 +642,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
+@@ -644,7 +644,8 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
int update_only = 0;
int cvs_exclude = 0;
int dry_run = 0;
-@@ -348,6 +349,7 @@ void usage(enum logcode F)
+@@ -352,6 +353,7 @@ void usage(enum logcode F)
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
rprintf(F," -O, --omit-dir-times omit directories from --times\n");
rprintf(F," --super receiver attempts super-user activities\n");
#ifdef SUPPORT_XATTRS
rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
-@@ -483,6 +485,9 @@ static struct poptOption long_options[] = {
+@@ -487,6 +489,9 @@ static struct poptOption long_options[] = {
{"times", 't', POPT_ARG_VAL, &preserve_times, 2, 0, 0 },
{"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
-@@ -1725,6 +1730,8 @@ void server_options(char **args, int *argc_p)
+@@ -1747,6 +1752,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -344,6 +344,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -345,6 +345,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
int updated = 0;
stat_x sx2;
int change_uid, change_gid;
mode_t new_mode = file->mode;
int inherit;
-@@ -387,18 +388,36 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -388,20 +389,39 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
set_xattr(fname, file, fnamecmp, sxp);
#endif
}
- if (ret == 0) /* ret == 1 if symlink could not be set */
- updated = 1;
-+ if (ret > 0) /* ret == 1 if symlink could not be set */
+- else if (receiver_symlink_times)
+- file->flags |= FLAG_TIME_FAILED;
++ if (ret > 0) { /* ret == 1 if symlink could not be set */
+ updated = 0;
++ if (receiver_symlink_times)
++ file->flags |= FLAG_TIME_FAILED;
++ }
}
change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
-@@ -528,7 +547,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -531,7 +551,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
/* Change permissions before putting the file into place. */
set_file_attrs(fnametmp, file, NULL, fnamecmp,
/* move tmp file over real file */
if (verbose > 2)
-@@ -555,7 +574,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -558,7 +578,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL, fnamecmp,
/* These flags are used in the live flist data. */
-@@ -148,6 +149,7 @@
+@@ -149,6 +150,7 @@
#define ATTRS_REPORT (1<<0)
#define ATTRS_SKIP_MTIME (1<<1)
#define FULL_FLUSH 1
#define NORMAL_FLUSH 0
-@@ -619,12 +621,14 @@ extern int file_extra_cnt;
+@@ -620,12 +622,14 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
dit(bf(--super)) This tells the receiving side to attempt super-user
activities even if the receiving rsync wasn't run by the super-user. These
activities include: preserving users via the bf(--owner) option, preserving
-@@ -1687,8 +1694,10 @@ quote(itemization(
+@@ -1689,8 +1696,10 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -95,6 +95,9 @@ extern uid_t our_uid;
+@@ -97,6 +97,9 @@ extern uid_t our_uid;
extern char *backup_dir;
extern char *backup_suffix;
extern int backup_suffix_len;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct filter_list_struct server_filter_list;
-@@ -136,10 +139,15 @@ enum delret {
+@@ -138,10 +141,15 @@ enum delret {
/* Forward declaration for delete_item(). */
static enum delret delete_dir_contents(char *fname, int flags);
}
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
-@@ -178,9 +186,9 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
+@@ -180,9 +188,9 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
if (S_ISDIR(mode)) {
what = "rmdir";
ok = do_rmdir(fbuf) == 0;
char *sockopts = NULL;
int rsync_port = 0;
int compare_dest = 0;
-@@ -320,6 +326,8 @@ void usage(enum logcode F)
+@@ -324,6 +330,8 @@ void usage(enum logcode F)
rprintf(F," -b, --backup make backups (see --suffix & --backup-dir)\n");
rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
rprintf(F," -u, --update skip files that are newer on the receiver\n");
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," --append append data onto shorter files\n");
-@@ -591,7 +599,9 @@ static struct poptOption long_options[] = {
+@@ -597,7 +605,9 @@ static struct poptOption long_options[] = {
{"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 },
{"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 },
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
{"list-only", 0, POPT_ARG_VAL, &list_only, 2, 0, 0 },
{"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
{"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
-@@ -1405,6 +1415,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1427,6 +1437,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
tmpdir = sanitize_path(NULL, tmpdir, NULL, 0);
if (backup_dir)
backup_dir = sanitize_path(NULL, backup_dir, NULL, 0);
}
if (server_filter_list.head && !am_sender) {
struct filter_list_struct *elp = &server_filter_list;
-@@ -1426,6 +1438,14 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1448,6 +1460,14 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
if (check_filter(elp, dir, 1) < 0)
goto options_rejected;
}
}
if (!backup_suffix)
-@@ -1437,6 +1457,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1459,6 +1479,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
backup_suffix);
return 0;
}
if (backup_dir) {
backup_dir_len = strlcpy(backup_dir_buf, backup_dir, sizeof backup_dir_buf);
backup_dir_remainder = sizeof backup_dir_buf - backup_dir_len;
-@@ -1460,6 +1489,30 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1482,6 +1511,30 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
"P *%s", backup_suffix);
parse_rule(&filter_list, backup_dir_buf, 0, 0);
}
if (make_backups && !backup_dir) {
omit_dir_times = 0; /* Implied, so avoid -O to sender. */
-@@ -1853,6 +1906,10 @@ void server_options(char **args, int *argc_p)
+@@ -1875,6 +1928,10 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--backup-dir";
args[ac++] = backup_dir;
}
/* Only send --suffix if it specifies a non-default value. */
if (strcmp(backup_suffix, backup_dir ? "" : BACKUP_SUFFIX) != 0) {
-@@ -1861,7 +1918,14 @@ void server_options(char **args, int *argc_p)
+@@ -1883,7 +1940,14 @@ void server_options(char **args, int *argc_p)
goto oom;
args[ac++] = arg;
}
diff --git a/log.c b/log.c
--- a/log.c
+++ b/log.c
-@@ -81,6 +81,7 @@ struct {
+@@ -82,6 +82,7 @@ struct {
{ RERR_TERMINATED , "sibling process terminated abnormally" },
{ RERR_SIGNAL1 , "received SIGUSR1" },
{ RERR_SIGNAL , "received SIGINT, SIGTERM, or SIGHUP" },
+ }
+ fclose(fp);
+
-+ clean_flist(checksum_flist, 0);
++ flist_sort_and_clean(checksum_flist, 0);
+}
+
int push_pathname(const char *dir, int len)
/* This code is only used by the receiver when it is building
* a list of files for a delete pass. */
if (keep_dirlinks && linkname_len && flist) {
-@@ -2074,7 +2272,11 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2074,7 +2272,8 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
* file-list to check if this is a 1-file xfer. */
send_extra_file_list(f, 1);
}
- }
+ } else
+ flist_eof = 1;
-+
-+ if (checksum_updating && always_checksum && flist_eof)
-+ read_checksums(NULL);
return flist;
}
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -38,6 +38,7 @@ extern int sanitize_paths;
+@@ -39,6 +39,7 @@ extern int numeric_ids;
extern int filesfrom_fd;
extern int remote_protocol;
extern int protocol_version;
extern int io_timeout;
extern int no_detach;
extern int write_batch;
-@@ -712,6 +713,8 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -746,6 +747,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;
+ counts_match = used == checksum_matches;
+ no_skipped = whole_dir && regular_skipped == 0;
+
-+ clean_flist(checksum_flist, 0);
++ flist_sort_and_clean(checksum_flist, 0);
+
+ checksum_flist->used = 0;
+ checksum_matches = 0;
if (f >= 0 && recurse && !divert_dirs) {
int i, end = flist->used - 1;
/* send_if_directory() bumps flist->used, so use "end". */
-@@ -2276,7 +2426,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+@@ -2274,6 +2424,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
+ }
+ } else
flist_eof = 1;
-
- if (checksum_updating && always_checksum && flist_eof)
-- read_checksums(NULL);
++
++ if (checksum_updating && always_checksum && flist_eof)
+ read_checksums(NULL); /* writes any last updates */
return flist;
diff --git a/loadparm.c b/loadparm.c
--- a/loadparm.c
+++ b/loadparm.c
-@@ -153,6 +153,7 @@ typedef struct
+@@ -154,6 +154,7 @@ typedef struct
int syslog_facility;
int timeout;
BOOL fake_super;
BOOL ignore_errors;
BOOL ignore_nonreadable;
-@@ -202,6 +203,7 @@ static service sDefault =
+@@ -205,6 +206,7 @@ static service sDefault =
/* syslog_facility; */ LOG_DAEMON,
/* timeout; */ 0,
/* fake_super; */ False,
/* ignore_errors; */ False,
/* ignore_nonreadable; */ False,
-@@ -301,6 +303,7 @@ static struct parm_struct parm_table[] =
- {"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0},
+@@ -306,6 +308,7 @@ static struct parm_struct parm_table[] =
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
+ {"charset", P_STRING, P_LOCAL, &sDefault.charset, NULL,0},
+ {"checksum updating", P_BOOL, P_LOCAL, &sDefault.checksum_updating, NULL,0},
{"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL,0},
{"dont compress", P_STRING, P_LOCAL, &sDefault.dont_compress, NULL,0},
{"exclude from", P_STRING, P_LOCAL, &sDefault.exclude_from, NULL,0},
-@@ -421,6 +424,7 @@ FN_LOCAL_INTEGER(lp_max_connections, max_connections)
- FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
+@@ -428,6 +431,7 @@ FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
+ FN_LOCAL_INTEGER(lp_syslog_facility, syslog_facility)
FN_LOCAL_INTEGER(lp_timeout, timeout)
+FN_LOCAL_BOOL(lp_checksum_updating, checksum_updating)
int max_delete = INT_MIN;
OFF_T max_size = 0;
OFF_T min_size = 0;
-@@ -312,6 +313,7 @@ void usage(enum logcode F)
+@@ -316,6 +317,7 @@ void usage(enum logcode F)
rprintf(F," -q, --quiet suppress non-error messages\n");
rprintf(F," --no-motd suppress daemon-mode MOTD (see manpage caveat)\n");
rprintf(F," -c, --checksum skip based on checksum, not mod-time & size\n");
rprintf(F," -a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)\n");
rprintf(F," --no-OPTION turn off an implied OPTION (e.g. --no-D)\n");
rprintf(F," -r, --recursive recurse into directories\n");
-@@ -560,6 +562,7 @@ static struct poptOption long_options[] = {
+@@ -566,6 +568,7 @@ static struct poptOption long_options[] = {
{"checksum", 'c', POPT_ARG_VAL, &always_checksum, 1, 0, 0 },
{"no-checksum", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 },
{"no-c", 0, POPT_ARG_VAL, &always_checksum, 0, 0, 0 },
{"block-size", 'B', POPT_ARG_LONG, &block_size, 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 },
-@@ -1966,7 +1969,9 @@ void server_options(char **args, int *argc_p)
+@@ -1988,7 +1991,9 @@ void server_options(char **args, int *argc_p)
args[ac++] = basis_dir[i];
}
}
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -679,6 +679,10 @@ extern int xattrs_ndx;
+@@ -680,6 +680,10 @@ extern int xattrs_ndx;
#define F_SUM(f) ((char*)OPT_EXTRA(f, LEN64_BUMP(f) + HLINK_BUMP(f) \
+ SUM_EXTRA_CNT - 1))
+
Note that rsync always verifies that each em(transferred) file was
correctly reconstructed on the receiving side by checking a whole-file
- checksum that is generated when as the file is transferred, but that
+ checksum that is generated as the file is transferred, but that
automatic after-the-transfer verification has nothing to do with this
option's before-the-transfer "Does this file need to be updated?" check.
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
-@@ -241,6 +241,20 @@ locking on this file to ensure that the max connections limit is not
+@@ -281,6 +281,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).
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -674,7 +674,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -683,7 +683,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
of the file time to determine whether to sync */
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -39,6 +39,7 @@ extern int preserve_acls;
+@@ -40,6 +40,7 @@ extern int preserve_acls;
extern int preserve_xattrs;
extern int preserve_links;
extern int preserve_devices;
+extern int copy_devices;
extern int preserve_specials;
extern int preserve_hard_links;
- extern int preserve_perms;
-@@ -1598,7 +1599,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+ extern int preserve_executability;
+@@ -1611,7 +1612,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
int preserve_links = 0;
int preserve_hard_links = 0;
int preserve_acls = 0;
-@@ -344,6 +345,7 @@ void usage(enum logcode F)
+@@ -348,6 +349,7 @@ void usage(enum logcode F)
rprintf(F," -o, --owner preserve owner (super-user only)\n");
rprintf(F," -g, --group preserve group\n");
rprintf(F," --devices preserve device files (super-user only)\n");
rprintf(F," --specials preserve special files\n");
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
-@@ -500,6 +502,7 @@ static struct poptOption long_options[] = {
+@@ -504,6 +506,7 @@ static struct poptOption long_options[] = {
{"no-D", 0, POPT_ARG_NONE, 0, OPT_NO_D, 0, 0 },
{"devices", 0, POPT_ARG_VAL, &preserve_devices, 1, 0, 0 },
{"no-devices", 0, POPT_ARG_VAL, &preserve_devices, 0, 0, 0 },
{"specials", 0, POPT_ARG_VAL, &preserve_specials, 1, 0, 0 },
{"no-specials", 0, POPT_ARG_VAL, &preserve_specials, 0, 0, 0 },
{"links", 'l', POPT_ARG_VAL, &preserve_links, 1, 0, 0 },
-@@ -2000,6 +2003,9 @@ void server_options(char **args, int *argc_p)
+@@ -2022,6 +2025,9 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
extern int am_root;
extern int am_server;
extern int am_sender;
-@@ -290,7 +291,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
+@@ -291,7 +292,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
if (iflags & ITEM_TRANSFER) {
int i = ndx - cur_flist->ndx_start;
-int uid_ndx, gid_ndx, fileflags_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
+int uid_ndx, gid_ndx, crtimes_ndx, fileflags_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
- #ifdef ICONV_OPTION
- int filesfrom_convert = 0;
-@@ -125,6 +126,8 @@ void setup_protocol(int f_out,int f_in)
+ int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
+
+@@ -135,6 +136,8 @@ void setup_protocol(int f_out,int f_in)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
gid_ndx = ++file_extra_cnt;
extern int verbose;
extern int dry_run;
-@@ -41,6 +42,7 @@ extern int preserve_links;
+@@ -41,6 +42,7 @@ extern int preserve_xattrs;
+ extern int preserve_links;
extern int preserve_devices;
extern int preserve_specials;
- extern int preserve_hard_links;
+extern int preserve_fileflags;
+ extern int preserve_hard_links;
+ extern int preserve_executability;
extern int preserve_perms;
- extern int preserve_times;
- extern int uid_ndx;
-@@ -137,6 +139,7 @@ enum delret {
+@@ -139,6 +141,7 @@ enum delret {
/* Forward declaration for delete_item(). */
static enum delret delete_dir_contents(char *fname, int flags);
static int is_backup_file(char *fn)
{
int k = strlen(fn) - backup_suffix_len;
-@@ -598,6 +601,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -603,6 +606,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP) && sxp->st.st_gid != (gid_t)F_GROUP(file))
return 0;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
-@@ -634,6 +644,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -642,6 +652,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
|| (keep_time && cmp_time(file->modtime, sxp->st.st_mtime) != 0))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -1173,6 +1189,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1182,6 +1198,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];
double len;
if (!F_IS_ACTIVE(f)) {
-@@ -1187,14 +1204,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1196,14 +1213,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -1277,6 +1296,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1290,6 +1309,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
return;
}
}
diff --git a/log.c b/log.c
--- a/log.c
+++ b/log.c
-@@ -642,7 +642,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
+@@ -644,7 +644,7 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
c[5] = !(iflags & ITEM_REPORT_PERMS) ? '.' : 'p';
c[6] = !(iflags & ITEM_REPORT_OWNER) ? '.' : 'o';
c[7] = !(iflags & ITEM_REPORT_GROUP) ? '.' : 'g';
int update_only = 0;
int cvs_exclude = 0;
int dry_run = 0;
-@@ -354,6 +355,7 @@ void usage(enum logcode F)
+@@ -358,6 +359,7 @@ void usage(enum logcode F)
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
rprintf(F," -O, --omit-dir-times omit directories from --times\n");
rprintf(F," --super receiver attempts super-user activities\n");
#ifdef SUPPORT_XATTRS
rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
-@@ -491,6 +493,9 @@ static struct poptOption long_options[] = {
+@@ -495,6 +497,9 @@ static struct poptOption long_options[] = {
{"times", 't', POPT_ARG_VAL, &preserve_times, 2, 0, 0 },
{"no-times", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"no-t", 0, POPT_ARG_VAL, &preserve_times, 0, 0, 0 },
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
-@@ -1742,6 +1747,8 @@ void server_options(char **args, int *argc_p)
+@@ -1764,6 +1769,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'D';
if (preserve_times)
argstr[x++] = 't';
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -436,6 +436,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
- if (ret == 0) /* ret == 1 if symlink could not be set */
- updated = 1;
+@@ -439,6 +439,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+ else if (receiver_symlink_times)
+ file->flags |= FLAG_TIME_FAILED;
}
+ if (crtimes_ndx && !(flags & ATTRS_SKIP_CRTIME)) {
+ time_t file_crtime = f_crtime(file);
change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
-@@ -573,7 +581,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -576,7 +584,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
/* Change permissions before putting the file into place. */
set_file_attrs(fnametmp, file, NULL, fnamecmp,
#ifdef SUPPORT_FLAGS
if (preserve_fileflags)
-@@ -608,7 +616,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -611,7 +619,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL, fnamecmp,
#define XMIT_SAME_FLAGS (1<<14) /* protocols ?? - now */
/* These flags are used in the live flist data. */
-@@ -149,6 +150,7 @@
+@@ -150,6 +151,7 @@
#define ATTRS_REPORT (1<<0)
#define ATTRS_SKIP_MTIME (1<<1)
#define FULL_FLUSH 1
#define NORMAL_FLUSH 0
-@@ -165,7 +167,7 @@
+@@ -166,7 +168,7 @@
#define FNAMECMP_FUZZY 0x83
/* For use by the itemize_changes code */
#define ITEM_REPORT_CHECKSUM (1<<1)
#define ITEM_REPORT_SIZE (1<<2)
#define ITEM_REPORT_TIME (1<<3)
-@@ -635,6 +637,7 @@ extern int file_extra_cnt;
+@@ -636,6 +638,7 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
extern int fileflags_ndx;
extern int acls_ndx;
extern int xattrs_ndx;
-@@ -642,6 +645,7 @@ extern int xattrs_ndx;
+@@ -643,6 +646,7 @@ extern int xattrs_ndx;
#define FILE_STRUCT_LEN (offsetof(struct file_struct, basename))
#define EXTRA_LEN (sizeof (union file_extras))
#define PTR_EXTRA_CNT ((sizeof (char *) + EXTRA_LEN - 1) / EXTRA_LEN)
#define DEV_EXTRA_CNT 2
#define DIRNODE_EXTRA_CNT 3
#define SUM_EXTRA_CNT ((MAX_DIGEST_LEN + EXTRA_LEN - 1) / EXTRA_LEN)
-@@ -896,6 +900,7 @@ typedef struct {
+@@ -897,6 +901,7 @@ typedef struct {
typedef struct {
STRUCT_STAT st;
type of update being done, bf(X) is replaced by the file-type, and the
other letters represent attributes that may be output if they are being
modified.
-@@ -1696,8 +1700,8 @@ quote(itemization(
+@@ -1698,8 +1702,8 @@ quote(itemization(
sender's value (requires bf(--owner) and super-user privileges).
it() A bf(g) means the group is different and is being updated to the
sender's value (requires bf(--group) and the authority to set the group).
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -145,6 +145,7 @@
+@@ -146,6 +146,7 @@
#define XFLG_OLD_PREFIXES (1<<1)
#define XFLG_ANCHORED2ABS (1<<2)
#define XFLG_ABS_IF_SLASH (1<<3)
diff --git a/access.c b/access.c
--- a/access.c
+++ b/access.c
-@@ -210,6 +210,43 @@ static int match_address(char *addr, char *tok)
+@@ -210,6 +210,42 @@ static int match_address(char *addr, char *tok)
return ret;
}
+static int match_hostlookup(char *addr, char *tok)
+{
-+ struct hostent *hp;
++ struct hostent *hp = NULL;
+ unsigned int i, len;
-+ int failed;
+ char *p;
+
+ if ((p = strchr(tok,'/')) != NULL) {
+ } else
+ len = strlen(tok);
+
-+ /* Fail quietly if tok is an address (not a hostname) */
-+ failed = strspn(tok, ".0123456789") == len;
++ /* Fail quietly (hp left NULL) if tok is an address, not a hostname. */
+#ifdef INET6
-+ failed ||= strchr(tok, ':') != NULL;
++ if (strchr(tok, ':') != NULL) {
++ ;
++ } else
+#endif
-+
-+ if (!failed && (hp = gethostbyname(tok)) == NULL)
-+ failed = 1;
++ if (strspn(tok, ".0123456789") != len)
++ hp = gethostbyname(tok);
+
+ if (p)
+ *p = '/';
+
-+ if (failed)
++ if (!hp)
+ return 0;
+
+ for (i = 0; hp->h_addr_list[i] != NULL; i++) {
static int access_match(char *list, char *addr, char *host)
{
char *tok;
-@@ -223,7 +260,7 @@ static int access_match(char *list, char *addr, char *host)
+@@ -223,7 +259,7 @@ static int access_match(char *list, char *addr, char *host)
strlower(host);
for (tok = strtok(list2, " ,\t"); tok; tok = strtok(NULL, " ,\t")) {
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -61,6 +61,7 @@ extern int append_mode;
+@@ -63,6 +63,7 @@ extern int append_mode;
extern int make_backups;
extern int csum_length;
extern int ignore_times;
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -667,6 +668,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -676,6 +677,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
{
int daemon_bwlimit = 0;
int bwlimit = 0;
int fuzzy_basis = 0;
-@@ -383,6 +384,7 @@ void usage(enum logcode F)
+@@ -387,6 +388,7 @@ void usage(enum logcode F)
rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n");
rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
rprintf(F," --size-only skip files that match in size\n");
rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
-@@ -523,6 +525,7 @@ static struct poptOption long_options[] = {
+@@ -527,6 +529,7 @@ static struct poptOption long_options[] = {
{"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
{"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
+ {"date-only", 0, POPT_ARG_NONE, &date_only, 0, 0, 0 },
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
- {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
- {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
-@@ -1905,6 +1908,9 @@ void server_options(char **args, int *argc_p)
+ {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+@@ -1927,6 +1930,9 @@ void server_options(char **args, int *argc_p)
}
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -194,7 +194,9 @@ static int fattr_find(struct file_struct *f, char *fname)
+@@ -196,7 +196,9 @@ static int fattr_find(struct file_struct *f, char *fname)
continue;
}
}
diff = u_strcmp(fmid->basename, f->basename);
if (diff == 0) {
good_match = mid;
-@@ -1894,6 +1896,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1907,6 +1909,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -388,6 +388,8 @@ void usage(enum logcode F)
+@@ -392,6 +392,8 @@ void usage(enum logcode F)
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
rprintf(F," --detect-renamed try to find renamed files to speed up 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");
-@@ -566,7 +568,9 @@ static struct poptOption long_options[] = {
+@@ -572,7 +574,9 @@ static struct poptOption long_options[] = {
{"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 },
{"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
{"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 },
{"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 },
-@@ -1901,8 +1905,14 @@ void server_options(char **args, int *argc_p)
+@@ -1923,8 +1927,14 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--super";
if (size_only)
args[ac++] = "--size-only";
extern int protect_args;
extern int preserve_uid;
extern int preserve_gid;
-@@ -107,6 +108,7 @@ void set_allow_inc_recurse(void)
+@@ -117,6 +118,7 @@ void set_allow_inc_recurse(void)
allow_inc_recurse = 0;
else if (!am_sender
&& (delete_before || delete_after
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -79,6 +79,7 @@ extern char *basis_dir[];
+@@ -81,6 +81,7 @@ extern char *basis_dir[];
extern int compare_dest;
extern int copy_dest;
extern int link_dest;
extern int whole_file;
extern int list_only;
extern int read_batch;
-@@ -97,6 +98,7 @@ extern char *backup_suffix;
+@@ -99,6 +100,7 @@ extern char *backup_suffix;
extern int backup_suffix_len;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct filter_list_struct server_filter_list;
int ignore_perishable = 0;
int non_perishable_cnt = 0;
-@@ -104,6 +106,7 @@ int maybe_ATTRS_REPORT = 0;
+@@ -106,6 +108,7 @@ int maybe_ATTRS_REPORT = 0;
static dev_t dev_zero;
static int deletion_count = 0; /* used to implement --max-delete */
static int deldelay_size = 0, deldelay_cnt = 0;
static char *deldelay_buf = NULL;
static int deldelay_fd = -1;
-@@ -113,7 +116,7 @@ static int need_retouch_dir_times;
+@@ -115,7 +118,7 @@ static int need_retouch_dir_times;
static int need_retouch_dir_perms;
static const char *solo_file = NULL;
#define DEL_OWNED_BY_US (1<<0) /* file/dir has our uid */
#define DEL_RECURSE (1<<1) /* if dir, delete all contents */
#define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */
-@@ -122,6 +125,7 @@ static const char *solo_file = NULL;
+@@ -124,6 +127,7 @@ static const char *solo_file = NULL;
#define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */
#define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */
#define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */
#define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL)
-@@ -142,11 +146,121 @@ static int is_backup_file(char *fn)
+@@ -144,11 +148,121 @@ static int is_backup_file(char *fn)
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
}
*/
static enum delret delete_item(char *fbuf, int mode, int flags)
{
-@@ -171,6 +285,8 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
+@@ -173,6 +287,8 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
goto check_ret;
/* OK: try to delete the directory. */
}
if (!(flags & DEL_MAKE_ROOM) && max_delete >= 0 && ++deletion_count > max_delete)
return DR_AT_LIMIT;
-@@ -226,6 +342,8 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
+@@ -228,6 +344,8 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
* its contents, otherwise just checks for content. Returns DR_SUCCESS or
* DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The
* buffer is used for recursion, but returned unchanged.)
*/
static enum delret delete_dir_contents(char *fname, int flags)
{
-@@ -245,7 +363,9 @@ static enum delret delete_dir_contents(char *fname, int flags)
+@@ -247,7 +365,9 @@ static enum delret delete_dir_contents(char *fname, int flags)
save_filters = push_local_filters(fname, dlen);
non_perishable_cnt = 0;
ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;
if (!dirlist->used)
-@@ -288,7 +408,8 @@ static enum delret delete_dir_contents(char *fname, int flags)
+@@ -290,7 +410,8 @@ static enum delret delete_dir_contents(char *fname, int flags)
do_chmod(fname, fp->mode |= S_IWUSR);
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
ret = DR_NOT_EMPTY;
if (delete_item(fname, fp->mode, flags) != DR_SUCCESS)
ret = DR_NOT_EMPTY;
}
-@@ -449,13 +570,18 @@ static void do_delayed_deletions(char *delbuf)
+@@ -451,13 +572,18 @@ static void do_delayed_deletions(char *delbuf)
* all the --delete-WHEN options. Note that the fbuf pointer must point to a
* MAXPATHLEN buffer with the name of the directory in it (the functions we
* call will append names onto the end, but the old dir value will be restored
if (!fbuf) {
change_local_filter_dir(NULL, 0, 0);
-@@ -465,21 +591,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -467,21 +593,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
if (verbose > 2)
rprintf(FINFO, "delete_in_dir(%s)\n", fbuf);
if (one_file_system) {
if (file->flags & FLAG_TOP_DIR)
filesystem_dev = *fs_dev;
-@@ -489,6 +622,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -491,6 +624,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
dirlist = get_dirlist(fbuf, dlen, 0);
/* If an item in dirlist is not found in flist, delete it
* from the filesystem. */
for (i = dirlist->used; i--; ) {
-@@ -501,18 +642,26 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -503,18 +644,26 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
f_name(fp, NULL));
continue;
}
flist_free(dirlist);
}
-@@ -542,9 +691,9 @@ static void do_delete_pass(void)
+@@ -544,9 +693,9 @@ static void do_delete_pass(void)
|| !S_ISDIR(st.st_mode))
continue;
if (do_progress && !am_server)
rprintf(FINFO, " \r");
-@@ -1170,6 +1319,7 @@ static void list_file_entry(struct file_struct *f)
+@@ -1179,6 +1328,7 @@ static void list_file_entry(struct file_struct *f)
}
}
static int phase = 0;
static int dflt_perms;
-@@ -1415,8 +1565,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1428,8 +1578,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
}
else if (delete_during && f_out != -1 && !phase && dry_run < 2
goto cleanup;
}
-@@ -1694,8 +1848,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1707,8 +1861,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
#endif
rsyserr(FERROR_XFER, stat_errno, "recv_generator: failed to stat %s",
full_fname(fname));
goto cleanup;
-@@ -2038,6 +2198,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -2051,6 +2211,12 @@ void generate_files(int f_out, const char *local_name)
if (verbose > 2)
rprintf(FINFO, "generator starting pid=%ld\n", (long)getpid());
if (delete_before && !solo_file && cur_flist->used > 0)
do_delete_pass();
if (delete_during == 2) {
-@@ -2048,7 +2214,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2061,7 +2227,7 @@ void generate_files(int f_out, const char *local_name)
}
do_progress = 0;
whole_file = 0;
if (verbose >= 2) {
rprintf(FINFO, "delta-transmission %s\n",
-@@ -2086,7 +2252,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2099,7 +2265,7 @@ void generate_files(int f_out, const char *local_name)
dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
} else
dirdev = MAKEDEV(0, 0);
}
}
}
-@@ -2129,7 +2295,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2142,7 +2308,21 @@ void generate_files(int f_out, const char *local_name)
} while ((cur_flist = cur_flist->next) != NULL);
if (delete_during)
int numeric_ids = 0;
int allow_8bit_chars = 0;
int force_delete = 0;
-@@ -386,6 +387,7 @@ void usage(enum logcode F)
+@@ -390,6 +391,7 @@ void usage(enum logcode F)
rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -y, --fuzzy find similar file for basis if no dest file\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");
-@@ -564,6 +566,7 @@ static struct poptOption long_options[] = {
+@@ -570,6 +572,7 @@ static struct poptOption long_options[] = {
{"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 },
{"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
{"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 },
{"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 },
-@@ -1542,7 +1545,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1564,7 +1567,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
inplace = 1;
}
partial_dir = tmp_partialdir;
if (inplace) {
-@@ -1551,6 +1554,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1573,6 +1576,7 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
snprintf(err_buf, sizeof err_buf,
"--%s cannot be used with --%s\n",
append_mode ? "append" : "inplace",
delay_updates ? "delay-updates" : "partial-dir");
return 0;
}
-@@ -1897,6 +1901,8 @@ void server_options(char **args, int *argc_p)
+@@ -1919,6 +1923,8 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--super";
if (size_only)
args[ac++] = "--size-only";
diff --git a/util.c b/util.c
--- a/util.c
+++ b/util.c
-@@ -1019,6 +1019,32 @@ int handle_partial_dir(const char *fname, int create)
+@@ -1022,6 +1022,32 @@ int handle_partial_dir(const char *fname, int create)
return 1;
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -54,6 +54,7 @@ extern int ignore_errors;
+@@ -56,6 +56,7 @@ extern int ignore_errors;
extern int remove_source_files;
extern int delay_updates;
extern int update_only;
extern int ignore_existing;
extern int ignore_non_existing;
extern int inplace;
-@@ -1635,6 +1636,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1648,6 +1649,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
-@@ -1951,6 +1959,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1964,6 +1972,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;
always_checksum = -always_checksum;
size_only = -size_only;
append_mode = -append_mode;
-@@ -1976,6 +1985,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -1989,6 +1998,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;
int cvs_exclude = 0;
int dry_run = 0;
int do_xfers = 1;
-@@ -321,6 +322,7 @@ void usage(enum logcode F)
+@@ -325,6 +326,7 @@ void usage(enum logcode F)
rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
rprintf(F," -u, --update skip files that are newer on the receiver\n");
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," --append append data onto shorter files\n");
rprintf(F," --append-verify like --append, but with old data in file checksum\n");
-@@ -525,6 +527,7 @@ static struct poptOption long_options[] = {
- {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
- {"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
+@@ -531,6 +533,7 @@ static struct poptOption long_options[] = {
+ {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
{"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
+ {"downdate", 'w', POPT_ARG_NONE, &downdate_only, 0, 0, 0 },
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -113,6 +113,10 @@ static int need_retouch_dir_times;
+@@ -115,6 +115,10 @@ static int need_retouch_dir_times;
static int need_retouch_dir_perms;
static const char *solo_file = NULL;
int cvs_exclude = 0;
int dry_run = 0;
int do_xfers = 1;
-@@ -321,6 +322,9 @@ void usage(enum logcode F)
+@@ -325,6 +326,9 @@ void usage(enum logcode F)
rprintf(F," --backup-dir=DIR make backups into hierarchy based in DIR\n");
rprintf(F," --suffix=SUFFIX set backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
rprintf(F," -u, --update skip files that are newer on the receiver\n");
rprintf(F," --inplace update destination files in-place (SEE MAN PAGE)\n");
rprintf(F," --append append data onto shorter files\n");
rprintf(F," --append-verify like --append, but with old data in file checksum\n");
-@@ -525,6 +529,9 @@ static struct poptOption long_options[] = {
- {"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
- {"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
+@@ -531,6 +535,9 @@ static struct poptOption long_options[] = {
+ {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
{"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
+#ifdef HAVE_POSIX_FADVISE64
+ {"drop-cache", 0, POPT_ARG_NONE, &drop_cache, 0, 0, 0 },
{"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-non-existing",0,POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
{"ignore-existing", 0, POPT_ARG_NONE, &ignore_existing, 0, 0, 0 },
-@@ -1671,6 +1678,11 @@ void server_options(char **args, int *argc_p)
+@@ -1693,6 +1700,11 @@ void server_options(char **args, int *argc_p)
if (!am_sender)
args[ac++] = "--sender";
-int uid_ndx, gid_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
+int uid_ndx, gid_ndx, fileflags_ndx, acls_ndx, xattrs_ndx, unsort_ndx;
- #ifdef ICONV_OPTION
- int filesfrom_convert = 0;
-@@ -124,6 +125,8 @@ void setup_protocol(int f_out,int f_in)
+ int receiver_symlink_times = 0; /* receiver can set the time on a symlink */
+
+@@ -134,6 +135,8 @@ void setup_protocol(int f_out,int f_in)
uid_ndx = ++file_extra_cnt;
if (preserve_gid)
gid_ndx = ++file_extra_cnt;
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -122,6 +122,7 @@ static const char *solo_file = NULL;
+@@ -124,6 +124,7 @@ static const char *solo_file = NULL;
#define DEL_FOR_SYMLINK (1<<5) /* making room for a replacement symlink */
#define DEL_FOR_DEVICE (1<<6) /* making room for a replacement device */
#define DEL_FOR_SPECIAL (1<<7) /* making room for a replacement special */
#define DEL_MAKE_ROOM (DEL_FOR_FILE|DEL_FOR_DIR|DEL_FOR_SYMLINK|DEL_FOR_DEVICE|DEL_FOR_SPECIAL)
-@@ -161,6 +162,10 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
+@@ -163,6 +164,10 @@ static enum delret delete_item(char *fbuf, int mode, int flags)
if (!am_root && !(mode & S_IWUSR) && flags & DEL_OWNED_BY_US)
do_chmod(fbuf, mode |= S_IWUSR);
if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
ignore_perishable = 1;
-@@ -282,6 +287,14 @@ static enum delret delete_dir_contents(char *fname, int flags)
+@@ -284,6 +289,14 @@ static enum delret delete_dir_contents(char *fname, int flags)
flags |= DEL_OWNED_BY_US;
else
flags &= ~DEL_OWNED_BY_US;
/* Save stack by recursing to ourself directly. */
if (S_ISDIR(fp->mode)) {
if (!am_root && !(fp->mode & S_IWUSR) && flags & DEL_OWNED_BY_US)
-@@ -341,15 +354,22 @@ static int flush_delete_delay(void)
+@@ -343,15 +356,22 @@ static int flush_delete_delay(void)
static int remember_delete(struct file_struct *file, const char *fname, int flags)
{
if ((deldelay_cnt += len) <= deldelay_size)
break;
if (deldelay_fd < 0 && !start_delete_delay_temp())
-@@ -362,10 +382,10 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
+@@ -364,10 +384,10 @@ static int remember_delete(struct file_struct *file, const char *fname, int flag
return 1;
}
char *bp, *past_space;
while (1) {
-@@ -405,9 +425,15 @@ static int read_delay_line(char *buf, int *own_flag_p)
+@@ -407,9 +427,15 @@ static int read_delay_line(char *buf, int *own_flag_p)
bp = deldelay_buf + read_pos;
if (*bp == '+') {
bp++;
if (sscanf(bp, "%x ", &mode) != 1) {
invalid_data:
-@@ -432,15 +458,15 @@ static int read_delay_line(char *buf, int *own_flag_p)
+@@ -434,15 +460,15 @@ static int read_delay_line(char *buf, int *own_flag_p)
static void do_delayed_deletions(char *delbuf)
{
if (deldelay_fd >= 0)
close(deldelay_fd);
}
-@@ -503,6 +529,9 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -505,6 +531,9 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
}
if (flist_find(cur_flist, fp) < 0) {
int flags = DEL_RECURSE
| (!uid_ndx || (uid_t)F_OWNER(fp) == our_uid ? DEL_OWNED_BY_US : 0);
f_name(fp, delbuf);
if (delete_during == 2) {
-@@ -1316,6 +1345,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1329,6 +1358,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
if (statret == 0 && sx.st.st_uid == our_uid)
del_opts |= DEL_OWNED_BY_US;
+ del_opts |= DEL_AN_IMMUTABLE;
+#endif
- if (S_ISDIR(file->mode)) {
+ if (is_dir) {
if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)
diff --git a/options.c b/options.c
--- a/options.c
int preserve_executability = 0;
int preserve_devices = 0;
int preserve_specials = 0;
-@@ -223,6 +224,7 @@ static void print_rsync_version(enum logcode f)
+@@ -224,6 +225,7 @@ static void print_rsync_version(enum logcode f)
char const *links = "no ";
char const *iconv = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
#if SUBPROTOCOL_VERSION != 0
-@@ -252,6 +254,9 @@ static void print_rsync_version(enum logcode f)
- #ifdef ICONV_OPTION
- iconv = "";
+@@ -256,6 +258,9 @@ static void print_rsync_version(enum logcode f)
+ #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+ symtimes = "";
#endif
+#ifdef SUPPORT_FLAGS
+ fileflags = "";
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -265,8 +270,8 @@ static void print_rsync_version(enum logcode f)
+@@ -269,8 +274,8 @@ static void print_rsync_version(enum logcode f)
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
-- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
-- have_inplace, acls, xattrs, iconv);
-+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %sfile-flags\n",
-+ have_inplace, acls, xattrs, iconv, fileflags);
+- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes\n",
+- have_inplace, acls, xattrs, iconv, symtimes);
++ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %sfile-flags\n",
++ have_inplace, acls, xattrs, iconv, symtimes, fileflags);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -333,6 +338,7 @@ void usage(enum logcode F)
+@@ -337,6 +342,7 @@ void usage(enum logcode F)
rprintf(F," -K, --keep-dirlinks treat symlinked dir on receiver as dir\n");
rprintf(F," -H, --hard-links preserve hard links\n");
rprintf(F," -p, --perms preserve permissions\n");
rprintf(F," -E, --executability preserve the file's executability\n");
rprintf(F," --chmod=CHMOD affect file and/or directory permissions\n");
#ifdef SUPPORT_ACLS
-@@ -473,6 +479,8 @@ static struct poptOption long_options[] = {
+@@ -477,6 +483,8 @@ static struct poptOption long_options[] = {
{"perms", 'p', POPT_ARG_VAL, &preserve_perms, 1, 0, 0 },
{"no-perms", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
{"no-p", 0, POPT_ARG_VAL, &preserve_perms, 0, 0, 0 },
{"executability", 'E', POPT_ARG_NONE, &preserve_executability, 0, 0, 0 },
{"acls", 'A', POPT_ARG_NONE, 0, 'A', 0, 0 },
{"no-acls", 0, POPT_ARG_VAL, &preserve_acls, 0, 0, 0 },
-@@ -1289,6 +1297,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1311,6 +1319,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
}
#endif
if (write_batch && read_batch) {
snprintf(err_buf, sizeof err_buf,
"--write-batch and --read-batch can not be used together\n");
-@@ -1804,6 +1821,9 @@ void server_options(char **args, int *argc_p)
+@@ -1826,6 +1843,9 @@ void server_options(char **args, int *argc_p)
if (xfer_dirs && !recurse && delete_mode && am_sender)
args[ac++] = "--no-r";
extern int preserve_executability;
extern int preserve_times;
extern int am_root;
-@@ -338,6 +339,41 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
+@@ -339,6 +340,41 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
return new_mode;
}
int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
const char *fnamecmp, int flags)
{
-@@ -469,6 +505,15 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -472,6 +508,15 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
}
#endif
+ if (preserve_fileflags && !S_ISLNK(sxp->st.st_mode)
+ && sxp->st.st_flags != F_FFLAGS(file)) {
+ if (!set_fileflags(fname, F_FFLAGS(file)))
-+ return 0;
++ goto cleanup;
+ updated = 1;
+ }
+#endif
if (verbose > 1 && flags & ATTRS_REPORT) {
if (updated)
rprintf(FCLIENT, "%s\n", fname);
-@@ -530,6 +575,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -533,6 +578,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
set_file_attrs(fnametmp, file, NULL, fnamecmp,
ok_to_set_time ? 0 : ATTRS_SKIP_MTIME);
/* move tmp file over real file */
if (verbose > 2)
rprintf(FINFO, "renaming %s to %s\n", fnametmp, fname);
-@@ -547,6 +596,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -550,6 +599,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
}
if (ret == 0) {
/* The file was moved into place (not copied), so it's done. */
/* These flags are used in the live flist data. */
-@@ -451,6 +452,21 @@ typedef unsigned int size_t;
+@@ -452,6 +453,21 @@ typedef unsigned int size_t;
#endif
#endif
/* Find a variable that is either exactly 32-bits or longer.
* If some code depends on 32-bit truncation, it will need to
* take special action in a "#if SIZEOF_INT32 > 4" section. */
-@@ -619,6 +635,7 @@ extern int file_extra_cnt;
+@@ -620,6 +636,7 @@ extern int file_extra_cnt;
extern int inc_recurse;
extern int uid_ndx;
extern int gid_ndx;
extern int acls_ndx;
extern int xattrs_ndx;
-@@ -656,6 +673,7 @@ extern int xattrs_ndx;
+@@ -657,6 +674,7 @@ extern int xattrs_ndx;
/* When the associated option is on, all entries will have these present: */
#define F_OWNER(f) REQ_EXTRA(f, uid_ndx)->unum
#define F_GROUP(f) REQ_EXTRA(f, gid_ndx)->unum
int preserve_links = 0;
int preserve_hard_links = 0;
int preserve_acls = 0;
-@@ -378,6 +379,7 @@ void usage(enum logcode F)
+@@ -382,6 +383,7 @@ void usage(enum logcode F)
rprintf(F," --partial-dir=DIR put a partially transferred file into DIR\n");
rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n");
rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
rprintf(F," --timeout=SECONDS set I/O timeout in seconds\n");
rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n");
-@@ -607,6 +609,7 @@ static struct poptOption long_options[] = {
+@@ -613,6 +615,7 @@ static struct poptOption long_options[] = {
{"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
{"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 },
{"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 },
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -1955,6 +1958,9 @@ void server_options(char **args, int *argc_p)
+@@ -1977,6 +1980,9 @@ void server_options(char **args, int *argc_p)
args[ac++] = tmpdir;
}
int blocking_io = -1;
int checksum_seed = 0;
int inplace = 0;
-@@ -403,6 +404,7 @@ void usage(enum logcode F)
+@@ -407,6 +408,7 @@ void usage(enum logcode F)
rprintf(F," --files-from=FILE read list of source-file names from FILE\n");
rprintf(F," -0, --from0 all *-from/filter files are delimited by 0s\n");
rprintf(F," -s, --protect-args no space-splitting; only wildcard special-chars\n");
rprintf(F," --address=ADDRESS bind address for outgoing socket to daemon\n");
rprintf(F," --port=PORT specify double-colon alternate port number\n");
rprintf(F," --sockopts=OPTIONS specify custom TCP options\n");
-@@ -596,6 +598,8 @@ static struct poptOption long_options[] = {
+@@ -602,6 +604,8 @@ static struct poptOption long_options[] = {
{"read-batch", 0, POPT_ARG_STRING, &batch_name, OPT_READ_BATCH, 0, 0 },
{"write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_WRITE_BATCH, 0, 0 },
{"only-write-batch", 0, POPT_ARG_STRING, &batch_name, OPT_ONLY_WRITE_BATCH, 0, 0 },
{"files-from", 0, POPT_ARG_STRING, &files_from, 0, 0, 0 },
{"from0", '0', POPT_ARG_VAL, &eol_nulls, 1, 0, 0},
{"no-from0", 0, POPT_ARG_VAL, &eol_nulls, 0, 0, 0},
-@@ -1917,6 +1921,9 @@ void server_options(char **args, int *argc_p)
+@@ -1939,6 +1943,9 @@ void server_options(char **args, int *argc_p)
args[ac++] = arg;
}
--port=PORT specify double-colon alternate port number
--sockopts=OPTIONS specify custom TCP options
@@ -1425,6 +1426,10 @@ If you use this option with bf(--iconv), the args will also be translated
- from the local to the remote character set. The translation happens before
+ from the local to the remote character-set. The translation happens before
wild-cards are expanded. See also the bf(--files-from) option.
+dit(bf(--ignore-case)) This option tells rsync to ignore upper-/lower-case
char *config_file = NULL;
char *shell_cmd = NULL;
char *logfile_name = NULL;
-@@ -389,6 +390,7 @@ void usage(enum logcode F)
+@@ -393,6 +394,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," -z, --compress compress file data during the transfer\n");
rprintf(F," --compress-level=NUM explicitly set compression level\n");
rprintf(F," --skip-compress=LIST skip compressing files with a suffix in LIST\n");
-@@ -441,7 +443,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -445,7 +447,7 @@ 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_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_APPEND,
-+ OPT_NO_D, OPT_APPEND, OPT_LINK_BY_HASH,
+- OPT_NO_D, OPT_APPEND, OPT_NO_ICONV,
++ OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_LINK_BY_HASH,
OPT_SERVER, OPT_REFUSED_BASE = 9000};
static struct poptOption long_options[] = {
-@@ -564,6 +566,7 @@ static struct poptOption long_options[] = {
+@@ -570,6 +572,7 @@ static struct poptOption long_options[] = {
{"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 },
{"fuzzy", 'y', POPT_ARG_NONE, &fuzzy_basis, 0, 0, 0 },
{"compress", 'z', POPT_ARG_NONE, 0, 'z', 0, 0 },
{"no-compress", 0, POPT_ARG_VAL, &do_compression, 0, 0, 0 },
-@@ -1226,6 +1229,21 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1244,6 +1247,21 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
return 0;
#endif
+#ifdef HAVE_LINK
+ arg = poptGetOptArg(pc);
+ if (sanitize_paths)
-+ arg = sanitize_path(NULL, arg, NULL, 0, NULL);
++ arg = sanitize_path(NULL, arg, NULL, 0);
+ link_by_hash_dir = (char *)arg;
+ break;
+#else
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -1975,6 +1993,11 @@ void server_options(char **args, int *argc_p)
+@@ -1997,6 +2015,11 @@ void server_options(char **args, int *argc_p)
} else if (inplace)
args[ac++] = "--inplace";
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -48,6 +48,7 @@ extern int inplace;
+@@ -49,6 +49,7 @@ extern int inplace;
extern int flist_eof;
extern int keep_dirlinks;
extern int make_backups;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct chmod_mode_struct *daemon_chmod_modes;
#ifdef ICONV_OPTION
-@@ -533,8 +534,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -536,8 +537,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);
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -817,6 +817,14 @@ struct stats {
+@@ -818,6 +818,14 @@ struct stats {
int num_transferred_files;
};
diff --git a/log.c b/log.c
--- a/log.c
+++ b/log.c
-@@ -56,6 +56,9 @@ extern char curr_dir[];
+@@ -57,6 +57,9 @@ extern char curr_dir[];
extern char *module_dir;
extern unsigned int module_dirlen;
static int log_initialised;
static int logfile_was_closed;
static FILE *logfile_fp;
-@@ -621,6 +624,19 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
+@@ -622,6 +625,19 @@ static void log_formatted(enum logcode code, const char *format, const char *op,
snprintf(buf2, sizeof buf2, fmt, (double)b);
n = buf2;
break;
+ break;
case 'i':
if (iflags & ITEM_DELETED) {
- n = "*deleting";
+ n = "*deleting ";
diff --git a/match.c b/match.c
--- a/match.c
+++ b/match.c
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -1476,7 +1476,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1498,7 +1498,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
else if (log_format_has(stdout_format, 'i'))
stdout_format_has_i = itemize_changes | 1;
if (!log_format_has(stdout_format, 'b')
diff --git a/rsync.yo b/rsync.yo
--- a/rsync.yo
+++ b/rsync.yo
-@@ -2065,7 +2065,7 @@ by the server and defaults to the current code(time()). This option
+@@ -2077,7 +2077,7 @@ by the server and defaults to the current code(time()). This option
is used to set a specific checksum seed, which is useful for
applications that want repeatable block and file checksums, or
in the case where the user wants a more random checksum seed.
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
--- a/rsyncd.conf.yo
+++ b/rsyncd.conf.yo
-@@ -464,7 +464,8 @@ quote(itemization(
+@@ -511,7 +511,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/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -59,6 +59,7 @@ char *auth_user;
+@@ -64,6 +64,7 @@ char *auth_user;
int read_only = 0;
int module_id = -1;
int munge_symlinks = 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;
+@@ -73,6 +74,7 @@ char *module_dir = NULL;
unsigned int module_dirlen = 0;
static int rl_nulls = 0;
#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)
+@@ -535,7 +537,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) || *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)
+
+@@ -631,6 +633,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
-@@ -793,6 +833,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
+@@ -844,6 +884,44 @@ static int rsync_module(int f_in, int f_out, int i, char *addr, char *host)
return 0;
}
diff --git a/loadparm.c b/loadparm.c
--- a/loadparm.c
+++ b/loadparm.c
-@@ -139,6 +139,7 @@ typedef struct
+@@ -140,6 +140,7 @@ typedef struct
char *log_file;
char *log_format;
char *name;
char *outgoing_chmod;
char *path;
char *postxfer_exec;
-@@ -188,6 +189,7 @@ static service sDefault =
+@@ -191,6 +192,7 @@ static service sDefault =
/* log_file; */ NULL,
/* log_format; */ "%o %h [%a] %m (%u) %f %l",
/* name; */ NULL,
/* outgoing_chmod; */ NULL,
/* path; */ NULL,
/* postxfer_exec; */ NULL,
-@@ -323,6 +325,7 @@ static struct parm_struct parm_table[] =
+@@ -328,6 +330,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},
+ {"numeric ids", P_BOOL, P_LOCAL, &sDefault.numeric_ids, 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)
+@@ -418,6 +421,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)
+ FN_LOCAL_STRING(lp_temp_dir, temp_dir)
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).
+@@ -160,10 +160,11 @@ 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
+ When this option 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
++bf(name converter) parameter to specify a conversion program, or it needs 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
+ code(getpwuid()), code(getgrgid()), code(getpwname()), and code(getgrnam())).
+-This means the rsync
++The latter choice means the rsync
+ process in the chroot hierarchy will need to have access to the resources
+ used by these library functions (traditionally /etc/passwd and
+ /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.
+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
+ dit(bf(charset)) This specifies the name of the character set in which the
+ module's filenames are stored. If the client uses an bf(--iconv) option,
+ the daemon will use the value of the "charset" parameter regardless of the
diff --git a/support/nameconvert b/support/nameconvert
new file mode 100755
--- /dev/null
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -43,6 +43,7 @@ extern int preserve_specials;
- extern int preserve_hard_links;
+@@ -45,6 +45,7 @@ extern int preserve_hard_links;
+ extern int preserve_executability;
extern int preserve_perms;
extern int preserve_times;
+extern int omit_dir_changes;
extern int uid_ndx;
extern int gid_ndx;
extern int delete_mode;
-@@ -597,6 +598,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
- int keep_time = !preserve_times ? 0
- : S_ISDIR(file->mode) ? preserve_times > 1
- : !S_ISLNK(file->mode);
+@@ -605,6 +606,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+ (receiver_symlink_times && !(file->flags & FLAG_TIME_FAILED)) ||
+ #endif
+ !S_ISLNK(file->mode);
+ int omit_changes = omit_dir_changes && S_ISDIR(sxp->st.st_mode);
if (S_ISREG(file->mode) && F_LENGTH(file) != sxp->st.st_size)
iflags |= ITEM_REPORT_SIZE;
-@@ -612,10 +614,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
- #endif
- if (!BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
+@@ -621,10 +623,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+ if ((preserve_perms || preserve_executability)
+ && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS))
iflags |= ITEM_REPORT_PERMS;
- if (uid_ndx && am_root && (uid_t)F_OWNER(file) != sxp->st.st_uid)
+ if (uid_ndx && am_root && !omit_changes
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
-@@ -1353,7 +1356,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1366,7 +1369,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
real_sx = sx;
if (file->flags & FLAG_DIR_CREATED)
statret = -1;
int update_only = 0;
int cvs_exclude = 0;
int dry_run = 0;
-@@ -348,6 +349,7 @@ void usage(enum logcode F)
+@@ -352,6 +353,7 @@ void usage(enum logcode F)
rprintf(F," -D same as --devices --specials\n");
rprintf(F," -t, --times preserve modification times\n");
rprintf(F," -O, --omit-dir-times omit directories from --times\n");
rprintf(F," --super receiver attempts super-user activities\n");
#ifdef SUPPORT_XATTRS
rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
-@@ -486,6 +488,7 @@ static struct poptOption long_options[] = {
+@@ -490,6 +492,7 @@ static struct poptOption long_options[] = {
{"omit-dir-times", 'O', POPT_ARG_VAL, &omit_dir_times, 1, 0, 0 },
{"no-omit-dir-times",0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"no-O", 0, POPT_ARG_VAL, &omit_dir_times, 0, 0, 0 },
{"modify-window", 0, POPT_ARG_INT, &modify_window, OPT_MODIFY_WINDOW, 0, 0 },
{"super", 0, POPT_ARG_VAL, &am_root, 2, 0, 0 },
{"no-super", 0, POPT_ARG_VAL, &am_root, 0, 0, 0 },
-@@ -1461,6 +1464,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1483,6 +1486,8 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
parse_rule(&filter_list, backup_dir_buf, 0, 0);
}
if (make_backups && !backup_dir) {
omit_dir_times = 0; /* Implied, so avoid -O to sender. */
if (preserve_times > 1)
-@@ -1699,6 +1704,8 @@ void server_options(char **args, int *argc_p)
+@@ -1721,6 +1726,8 @@ void server_options(char **args, int *argc_p)
argstr[x++] = 'm';
if (omit_dir_times)
argstr[x++] = 'O';
extern int am_root;
extern int am_server;
extern int am_sender;
-@@ -401,9 +402,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
- updated = 1;
+@@ -404,9 +405,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+ file->flags |= FLAG_TIME_FAILED;
}
- change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
extern int rsync_port;
extern int ignore_errors;
extern int kluge_around_eof;
-@@ -115,8 +118,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
+@@ -121,8 +124,18 @@ int start_socket_client(char *host, int remote_argc, char *remote_argv[],
set_socket_options(fd, sockopts);
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)
-@@ -259,6 +272,32 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -265,6 +278,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,
-@@ -284,6 +323,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -290,6 +329,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);
}
-@@ -291,6 +334,10 @@ int start_inband_exchange(int f_in, int f_out, const char *user, int argc, char
+@@ -297,6 +340,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;
}
-@@ -843,6 +890,9 @@ int start_daemon(int f_in, int f_out)
+@@ -894,6 +941,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;
-@@ -854,6 +904,20 @@ int start_daemon(int f_in, int f_out)
+@@ -905,6 +955,20 @@ int start_daemon(int f_in, int f_out)
return -1;
}
#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
char *batch_name = NULL;
-@@ -223,6 +231,7 @@ static void print_rsync_version(enum logcode f)
+@@ -224,6 +232,7 @@ static void print_rsync_version(enum logcode f)
char const *links = "no ";
char const *iconv = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
#if SUBPROTOCOL_VERSION != 0
-@@ -252,6 +261,9 @@ static void print_rsync_version(enum logcode f)
- #ifdef ICONV_OPTION
- iconv = "";
+@@ -256,6 +265,9 @@ static void print_rsync_version(enum logcode f)
+ #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+ symtimes = "";
#endif
+#ifdef HAVE_OPENSSL
+ ssl = "";
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -265,8 +277,8 @@ static void print_rsync_version(enum logcode f)
+@@ -269,8 +281,8 @@ static void print_rsync_version(enum logcode f)
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
-- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
-- have_inplace, acls, xattrs, iconv);
-+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %sSSL\n",
-+ have_inplace, acls, xattrs, iconv, ssl);
+- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes\n",
+- have_inplace, acls, xattrs, iconv, symtimes);
++ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %sSSL\n",
++ have_inplace, acls, xattrs, iconv, symtimes, ssl);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -428,6 +440,13 @@ void usage(enum logcode F)
+@@ -432,6 +444,13 @@ void usage(enum logcode F)
#endif
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
rprintf(F," --version print version number\n");
rprintf(F,"(-h) --help show this help (-h works with no other options)\n");
-@@ -441,7 +460,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -445,7 +464,7 @@ 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_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_APPEND,
-+ OPT_NO_D, OPT_APPEND, OPT_USE_SSL,
+- OPT_NO_D, OPT_APPEND, OPT_NO_ICONV,
++ OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_USE_SSL,
OPT_SERVER, OPT_REFUSED_BASE = 9000};
static struct poptOption long_options[] = {
-@@ -627,6 +646,13 @@ static struct poptOption long_options[] = {
+@@ -634,6 +653,13 @@ static struct poptOption long_options[] = {
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 },
{"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 },
/* All the following options switch us into daemon-mode option-parsing. */
{"config", 0, POPT_ARG_STRING, 0, OPT_DAEMON, 0, 0 },
{"daemon", 0, POPT_ARG_NONE, 0, OPT_DAEMON, 0, 0 },
-@@ -652,6 +678,13 @@ static void daemon_usage(enum logcode F)
+@@ -659,6 +685,13 @@ static void daemon_usage(enum logcode F)
rprintf(F," -v, --verbose increase verbosity\n");
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
rprintf(F," --help show this help screen\n");
rprintf(F,"\n");
-@@ -676,6 +709,13 @@ static struct poptOption long_daemon_options[] = {
+@@ -683,6 +716,13 @@ static struct poptOption long_daemon_options[] = {
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, &am_server, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
{"verbose", 'v', POPT_ARG_NONE, 0, 'v', 0, 0 },
{"no-verbose", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
{"no-v", 0, POPT_ARG_VAL, &verbose, 0, 0, 0 },
-@@ -950,6 +990,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -962,6 +1002,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
verbose++;
break;
default:
rprintf(FERROR,
"rsync: %s: %s (in daemon mode)\n",
-@@ -973,6 +1019,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -985,6 +1031,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
exit_cleanup(RERR_SYNTAX);
}
*argv_p = argv = poptGetArgs(pc);
*argc_p = argc = count_args(argv);
am_starting_up = 0;
-@@ -1226,6 +1283,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1244,6 +1301,12 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
return 0;
#endif
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -1545,6 +1608,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1567,6 +1630,17 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
if (delay_updates && !partial_dir)
partial_dir = tmp_partialdir;
if (inplace) {
#ifdef HAVE_FTRUNCATE
if (partial_dir) {
-@@ -2019,10 +2093,27 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
+@@ -2041,10 +2115,27 @@ char *check_for_hostspec(char *s, char **host_ptr, int *port_ptr)
char *p;
int not_host;
int hostlen;
#define SYMLINK_PREFIX "/rsyncd-munged/"
#define SYMLINK_PREFIX_LEN ((int)sizeof SYMLINK_PREFIX - 1)
-@@ -536,6 +537,11 @@ typedef unsigned int size_t;
+@@ -537,6 +538,11 @@ typedef unsigned int size_t;
# define SIZEOF_INT64 SIZEOF_OFF_T
#endif
int do_compression = 0;
int def_compress_level = Z_DEFAULT_COMPRESSION;
int am_root = 0; /* 0 = normal, 1 = root, 2 = --super, -1 = --fake-super */
-@@ -223,6 +224,7 @@ static void print_rsync_version(enum logcode f)
+@@ -224,6 +225,7 @@ static void print_rsync_version(enum logcode f)
char const *links = "no ";
char const *iconv = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
#if SUBPROTOCOL_VERSION != 0
-@@ -252,6 +254,9 @@ static void print_rsync_version(enum logcode f)
- #ifdef ICONV_OPTION
- iconv = "";
+@@ -256,6 +258,9 @@ static void print_rsync_version(enum logcode f)
+ #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+ symtimes = "";
#endif
+#ifdef SUPPORT_PREALLOCATION
+ preallocation = "";
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -265,8 +270,8 @@ static void print_rsync_version(enum logcode f)
+@@ -269,8 +274,8 @@ static void print_rsync_version(enum logcode f)
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
-- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
-- have_inplace, acls, xattrs, iconv);
-+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %spreallocation\n",
-+ have_inplace, acls, xattrs, iconv, preallocation);
+- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes\n",
+- have_inplace, acls, xattrs, iconv, symtimes);
++ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %spreallocation\n",
++ have_inplace, acls, xattrs, iconv, symtimes, preallocation);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
-@@ -353,6 +358,9 @@ void usage(enum logcode F)
+@@ -357,6 +362,9 @@ void usage(enum logcode F)
rprintf(F," --fake-super store/recover privileged attrs using xattrs\n");
#endif
rprintf(F," -S, --sparse handle sparse files efficiently\n");
rprintf(F," -n, --dry-run perform a trial run with no changes made\n");
rprintf(F," -W, --whole-file copy files whole (without delta-xfer algorithm)\n");
rprintf(F," -x, --one-file-system don't cross filesystem boundaries\n");
-@@ -531,6 +539,7 @@ static struct poptOption long_options[] = {
+@@ -537,6 +545,7 @@ static struct poptOption long_options[] = {
{"max-size", 0, POPT_ARG_STRING, &max_size_arg, OPT_MAX_SIZE, 0, 0 },
{"min-size", 0, POPT_ARG_STRING, &min_size_arg, OPT_MIN_SIZE, 0, 0 },
{"sparse", 'S', POPT_ARG_NONE, &sparse_files, 0, 0, 0 },
{"inplace", 0, POPT_ARG_NONE, &inplace, 0, 0, 0 },
{"append", 0, POPT_ARG_NONE, 0, OPT_APPEND, 0, 0 },
{"append-verify", 0, POPT_ARG_VAL, &append_mode, 2, 0, 0 },
-@@ -1289,6 +1298,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1311,6 +1320,15 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
}
#endif
if (write_batch && read_batch) {
snprintf(err_buf, sizeof err_buf,
"--write-batch and --read-batch can not be used together\n");
-@@ -2000,6 +2018,9 @@ void server_options(char **args, int *argc_p)
+@@ -2022,6 +2040,9 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -601,6 +601,10 @@ struct ht_int64_node {
+@@ -602,6 +602,10 @@ struct ht_int64_node {
#define ACLS_NEED_MASK 1
#endif
size_t bwlimit_writemax = 0;
int ignore_existing = 0;
int ignore_non_existing = 0;
-@@ -419,6 +420,7 @@ void usage(enum logcode F)
+@@ -423,6 +424,7 @@ void usage(enum logcode F)
rprintf(F," --password-file=FILE read daemon-access password from FILE\n");
rprintf(F," --list-only list the files instead of copying them\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
-@@ -586,6 +588,7 @@ static struct poptOption long_options[] = {
+@@ -592,6 +594,7 @@ static struct poptOption long_options[] = {
{"itemize-changes", 'i', POPT_ARG_NONE, 0, 'i', 0, 0 },
{"no-itemize-changes",0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
{"no-i", 0, POPT_ARG_VAL, &itemize_changes, 0, 0, 0 },
diff --git a/clientserver.c b/clientserver.c
--- a/clientserver.c
+++ b/clientserver.c
-@@ -977,6 +977,13 @@ int daemon_main(void)
+@@ -1028,6 +1028,13 @@ int daemon_main(void)
* address too. In fact, why not just do inet_ntop on the
* local address??? */
} global;
static global Globals;
-@@ -298,6 +301,9 @@ static struct parm_struct parm_table[] =
+@@ -302,6 +305,9 @@ static struct parm_struct parm_table[] =
{"motd file", P_STRING, P_GLOBAL,&Globals.motd_file, NULL,0},
{"pid file", P_STRING, P_GLOBAL,&Globals.pid_file, NULL,0},
{"port", P_INTEGER,P_GLOBAL,&Globals.rsync_port, NULL,0},
{"socket options", P_STRING, P_GLOBAL,&Globals.socket_options, NULL,0},
{"auth users", P_STRING, P_LOCAL, &sDefault.auth_users, NULL,0},
-@@ -390,6 +396,9 @@ FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
+@@ -396,6 +402,9 @@ FN_GLOBAL_STRING(lp_pid_file, &Globals.pid_file)
FN_GLOBAL_STRING(lp_socket_options, &Globals.socket_options)
FN_GLOBAL_INTEGER(lp_rsync_port, &Globals.rsync_port)
+#endif
FN_LOCAL_STRING(lp_auth_users, auth_users)
- FN_LOCAL_STRING(lp_comment, comment)
+ FN_LOCAL_STRING(lp_charset, charset)
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
diff --git a/options.c b/options.c
--- a/options.c
+++ b/options.c
-@@ -223,6 +223,7 @@ static void print_rsync_version(enum logcode f)
+@@ -224,6 +224,7 @@ static void print_rsync_version(enum logcode f)
char const *links = "no ";
char const *iconv = "no ";
char const *ipv6 = "no ";
STRUCT_STAT *dumstat;
#if SUBPROTOCOL_VERSION != 0
-@@ -252,6 +253,9 @@ static void print_rsync_version(enum logcode f)
- #ifdef ICONV_OPTION
- iconv = "";
+@@ -256,6 +257,9 @@ static void print_rsync_version(enum logcode f)
+ #if defined HAVE_LUTIMES && defined HAVE_UTIMES
+ symtimes = "";
#endif
+#if HAVE_LIBSLP
+ slp = "";
rprintf(f, "%s version %s protocol version %d%s\n",
RSYNC_NAME, RSYNC_VERSION, PROTOCOL_VERSION, subprotocol);
-@@ -265,8 +269,8 @@ static void print_rsync_version(enum logcode f)
+@@ -269,8 +273,8 @@ static void print_rsync_version(enum logcode f)
(int)(sizeof (int64) * 8));
rprintf(f, " %ssocketpairs, %shardlinks, %ssymlinks, %sIPv6, batchfiles, %sinplace,\n",
got_socketpair, hardlinks, links, ipv6, have_inplace);
-- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv\n",
-- have_inplace, acls, xattrs, iconv);
-+ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %sSLP\n",
-+ have_inplace, acls, xattrs, iconv, slp);
+- rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes\n",
+- have_inplace, acls, xattrs, iconv, symtimes);
++ rprintf(f, " %sappend, %sACLs, %sxattrs, %siconv, %ssymtimes, %sSLP\n",
++ have_inplace, acls, xattrs, iconv, symtimes, slp);
#ifdef MAINTAINER_MODE
rprintf(f, "Panic Action: \"%s\"\n", get_panic_action());
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -186,6 +186,10 @@
+@@ -187,6 +187,10 @@
#define SIGNIFICANT_ITEM_FLAGS (~(\
ITEM_BASIS_TYPE_FOLLOWS | ITEM_XNAME_FOLLOWS | ITEM_LOCAL_CHANGE))
enddit()
-@@ -607,6 +616,7 @@ use chroot = no
+@@ -654,6 +663,7 @@ use chroot = yes
max connections = 4
syslog facility = local5
pid file = /var/run/rsyncd.pid
+slp refresh = 3600
[ftp]
- path = /var/ftp/pub
+ path = /var/ftp/./pub
diff --git a/socket.c b/socket.c
--- a/socket.c
+++ b/socket.c
/**
* If 1, send the whole file as literal data rather than trying to
-@@ -362,6 +363,7 @@ void usage(enum logcode F)
+@@ -366,6 +367,7 @@ void usage(enum logcode F)
rprintf(F," --existing skip creating new files on receiver\n");
rprintf(F," --ignore-existing skip updating files that already exist on receiver\n");
rprintf(F," --remove-source-files sender removes synchronized files (non-dirs)\n");
rprintf(F," --del an alias for --delete-during\n");
rprintf(F," --delete delete extraneous files from destination dirs\n");
rprintf(F," --delete-before receiver deletes before transfer, not during\n");
-@@ -589,6 +591,7 @@ static struct poptOption long_options[] = {
+@@ -595,6 +597,7 @@ static struct poptOption long_options[] = {
{"bwlimit", 0, POPT_ARG_INT, &bwlimit, 0, 0, 0 },
{"no-bwlimit", 0, POPT_ARG_VAL, &bwlimit, 0, 0, 0 },
{"backup", 'b', POPT_ARG_VAL, &make_backups, 1, 0, 0 },
{"no-backup", 0, POPT_ARG_VAL, &make_backups, 0, 0, 0 },
{"backup-dir", 0, POPT_ARG_STRING, &backup_dir, 0, 0, 0 },
{"suffix", 0, POPT_ARG_STRING, &backup_suffix, 0, 0, 0 },
-@@ -1903,6 +1906,8 @@ void server_options(char **args, int *argc_p)
+@@ -1925,6 +1928,8 @@ void server_options(char **args, int *argc_p)
goto oom;
args[ac++] = arg;
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -61,6 +61,7 @@ extern int append_mode;
+@@ -63,6 +63,7 @@ extern int append_mode;
extern int make_backups;
extern int csum_length;
extern int ignore_times;
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -667,7 +668,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -676,7 +677,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
/* Perform our quick-check heuristic for determining if a file is unchanged. */
int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
{
char *rsync_path = RSYNC_PATH;
char *backup_dir = NULL;
char backup_dir_buf[MAXPATHLEN];
-@@ -383,6 +386,7 @@ void usage(enum logcode F)
+@@ -387,6 +390,7 @@ void usage(enum logcode F)
rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n");
rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
rprintf(F," --size-only skip files that match in size\n");
rprintf(F," --modify-window=NUM compare mod-times with reduced accuracy\n");
rprintf(F," -T, --temp-dir=DIR create temporary files in directory DIR\n");
rprintf(F," -y, --fuzzy find similar file for basis if no dest file\n");
-@@ -422,6 +426,8 @@ void usage(enum logcode F)
+@@ -426,6 +430,8 @@ void usage(enum logcode F)
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
rprintf(F," --protocol=NUM force an older protocol version to be used\n");
#ifdef ICONV_OPTION
rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filenames\n");
-@@ -523,6 +529,7 @@ static struct poptOption long_options[] = {
+@@ -527,6 +533,7 @@ static struct poptOption long_options[] = {
{"chmod", 0, POPT_ARG_STRING, 0, OPT_CHMOD, 0, 0 },
{"ignore-times", 'I', POPT_ARG_NONE, &ignore_times, 0, 0, 0 },
{"size-only", 0, POPT_ARG_NONE, &size_only, 0, 0, 0 },
+ {"times-only", 0, POPT_ARG_NONE, ×_only , 0, 0, 0 },
{"one-file-system", 'x', POPT_ARG_NONE, 0, 'x', 0, 0 },
- {"update", 'u', POPT_ARG_NONE, &update_only, 0, 0, 0 },
- {"existing", 0, POPT_ARG_NONE, &ignore_non_existing, 0, 0, 0 },
-@@ -623,6 +630,8 @@ static struct poptOption long_options[] = {
+ {"no-one-file-system",'x',POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+ {"no-x", 'x', POPT_ARG_VAL, &one_file_system, 0, 0, 0 },
+@@ -630,6 +637,8 @@ static struct poptOption long_options[] = {
{"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
{"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
{"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 },
-@@ -1586,6 +1595,16 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1608,6 +1617,16 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
}
}
if (files_from) {
char *h, *p;
int q;
-@@ -1905,6 +1924,25 @@ void server_options(char **args, int *argc_p)
+@@ -1927,6 +1946,25 @@ void server_options(char **args, int *argc_p)
}
}
diff --git a/rsync.h b/rsync.h
--- a/rsync.h
+++ b/rsync.h
-@@ -132,6 +132,7 @@
+@@ -133,6 +133,7 @@
#define IOERR_DEL_LIMIT (1<<2)
#define MAX_ARGS 1000
--protocol=NUM force an older protocol version to be used
--iconv=CONVERT_SPEC request charset conversion of filenames
--checksum-seed=NUM set block/file checksum seed (advanced)
-@@ -2021,6 +2024,33 @@ file previously generated by bf(--write-batch).
+@@ -2023,6 +2026,33 @@ file previously generated by bf(--write-batch).
If em(FILE) is bf(-), the batch data will be read from standard input.
See the "BATCH MODE" section for details.
@@ -203,6 +203,7 @@ static int refused_delete, refused_archive_part, refused_compress;
static int refused_partial, refused_progress, refused_delete_before;
static int refused_delete_during;
- static int refused_inplace;
+ static int refused_inplace, refused_no_iconv;
+static char *stdout_buffering;
static char *max_size_arg, *min_size_arg;
static char tmp_partialdir[] = ".~tmp~";
-@@ -419,6 +420,7 @@ void usage(enum logcode F)
+@@ -423,6 +424,7 @@ void usage(enum logcode F)
rprintf(F," --password-file=FILE read daemon-access password from FILE\n");
rprintf(F," --list-only list the files instead of copying them\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
-@@ -623,6 +625,7 @@ static struct poptOption long_options[] = {
+@@ -630,6 +632,7 @@ static struct poptOption long_options[] = {
{"password-file", 0, POPT_ARG_STRING, &password_file, 0, 0, 0 },
{"blocking-io", 0, POPT_ARG_VAL, &blocking_io, 1, 0, 0 },
{"no-blocking-io", 0, POPT_ARG_VAL, &blocking_io, 0, 0, 0 },
{"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 },
{"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 },
{"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 },
-@@ -1241,6 +1244,13 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1259,6 +1262,13 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
}
}
int max_delete = INT_MIN;
OFF_T max_size = 0;
OFF_T min_size = 0;
-@@ -419,6 +420,8 @@ void usage(enum logcode F)
+@@ -423,6 +424,8 @@ void usage(enum logcode F)
rprintf(F," --password-file=FILE read daemon-access password from FILE\n");
rprintf(F," --list-only list the files instead of copying them\n");
rprintf(F," --bwlimit=KBPS limit I/O bandwidth; KBytes per second\n");
rprintf(F," --write-batch=FILE write a batched update to FILE\n");
rprintf(F," --only-write-batch=FILE like --write-batch but w/o updating destination\n");
rprintf(F," --read-batch=FILE read a batched update from FILE\n");
-@@ -441,7 +444,7 @@ enum {OPT_VERSION = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM,
+@@ -445,7 +448,7 @@ 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_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_APPEND,
-+ OPT_NO_D, OPT_APPEND, OPT_STOP_AT, OPT_TIME_LIMIT,
+- OPT_NO_D, OPT_APPEND, OPT_NO_ICONV,
++ OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_STOP_AT, OPT_TIME_LIMIT,
OPT_SERVER, OPT_REFUSED_BASE = 9000};
static struct poptOption long_options[] = {
-@@ -607,6 +610,8 @@ static struct poptOption long_options[] = {
+@@ -613,6 +616,8 @@ static struct poptOption long_options[] = {
{"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
{"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 },
{"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 },
{"rsh", 'e', POPT_ARG_STRING, &shell_cmd, 0, 0, 0 },
{"rsync-path", 0, POPT_ARG_STRING, &rsync_path, 0, 0, 0 },
{"temp-dir", 'T', POPT_ARG_STRING, &tmpdir, 0, 0, 0 },
-@@ -1226,6 +1231,36 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1244,6 +1249,36 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
return 0;
#endif
default:
/* A large opt value means that set_refuse_options()
* turned this option off. */
-@@ -1849,6 +1884,15 @@ void server_options(char **args, int *argc_p)
+@@ -1871,6 +1906,15 @@ void server_options(char **args, int *argc_p)
args[ac++] = arg;
}
--write-batch=FILE write a batched update to FILE
--only-write-batch=FILE like --write-batch but w/o updating dest
--read-batch=FILE read a batched update from FILE
-@@ -1995,6 +1997,19 @@ transfer was too fast, it will wait before sending the next data block. The
+@@ -1997,6 +1999,19 @@ transfer was too fast, it will wait before sending the next data block. The
result is an average transfer rate equaling the specified limit. A value
of zero specifies no limit.
#define MAX_BATCH_NAME_LEN 256 /* Must be less than MAXPATHLEN-13 */
char *batch_name = NULL;
-@@ -426,6 +428,7 @@ void usage(enum logcode F)
+@@ -430,6 +432,7 @@ void usage(enum logcode F)
#ifdef ICONV_OPTION
rprintf(F," --iconv=CONVERT_SPEC request charset conversion of filenames\n");
#endif
rprintf(F," -4, --ipv4 prefer IPv4\n");
rprintf(F," -6, --ipv6 prefer IPv6\n");
rprintf(F," --version print version number\n");
-@@ -613,6 +616,7 @@ static struct poptOption long_options[] = {
- #ifdef ICONV_OPTION
+@@ -620,6 +623,7 @@ static struct poptOption long_options[] = {
{"iconv", 0, POPT_ARG_STRING, &iconv_opt, 0, 0, 0 },
+ {"no-iconv", 0, POPT_ARG_NONE, 0, OPT_NO_ICONV, 0, 0 },
#endif
+ {"tr", 0, POPT_ARG_STRING, &tr_opt, 0, 0, 0 },
{"ipv4", '4', POPT_ARG_VAL, &default_af_hint, AF_INET, 0, 0 },
{"ipv6", '6', POPT_ARG_VAL, &default_af_hint, AF_INET6, 0, 0 },
{"8-bit-output", '8', POPT_ARG_NONE, &allow_8bit_chars, 0, 0, 0 },
-@@ -1632,6 +1636,31 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
+@@ -1654,6 +1658,31 @@ int parse_arguments(int *argc_p, const char ***argv_p, int frommain)
}
}
am_starting_up = 0;
return 1;
-@@ -2000,6 +2029,12 @@ void server_options(char **args, int *argc_p)
+@@ -2022,6 +2051,12 @@ void server_options(char **args, int *argc_p)
else if (remove_source_files)
args[ac++] = "--remove-sent-files";
--checksum-seed=NUM set block/file checksum seed (advanced)
-4, --ipv4 prefer IPv4
-6, --ipv6 prefer IPv6
-@@ -2049,6 +2050,22 @@ specifying matching rules that can match on both sides of the transfer.
- For instance, you can specify extra include/exclude rules if there are
- filename differences on the two sides that need to be accounted for.
+@@ -2061,6 +2062,22 @@ daemon uses the charset specified in its "charset" configuration parameter
+ regardless of the remote charset you actually pass. Thus, you may feel free to
+ specify just the local charset for a daemon transfer (e.g. bf(--iconv=utf8)).
+dit(bf(--tr=BAD/GOOD)) Transliterates filenames on the receiver, after the
+iconv conversion (if any). This can be used to remove characters illegal
int rsync_port = 0;
int compare_dest = 0;
int copy_dest = 0;
-@@ -379,6 +381,8 @@ void usage(enum logcode F)
+@@ -383,6 +385,8 @@ void usage(enum logcode F)
rprintf(F," --delay-updates put all updated files into place at transfer's end\n");
rprintf(F," -m, --prune-empty-dirs prune empty directory chains from the file-list\n");
rprintf(F," --numeric-ids don't map uid/gid values by user/group name\n");
rprintf(F," --timeout=SECONDS set I/O timeout in seconds\n");
rprintf(F," --contimeout=SECONDS set daemon connection timeout in seconds\n");
rprintf(F," -I, --ignore-times don't skip files that match in size and mod-time\n");
-@@ -604,6 +608,8 @@ static struct poptOption long_options[] = {
+@@ -610,6 +614,8 @@ static struct poptOption long_options[] = {
{"no-s", 0, POPT_ARG_VAL, &protect_args, 0, 0, 0},
{"numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 1, 0, 0 },
{"no-numeric-ids", 0, POPT_ARG_VAL, &numeric_ids, 0, 0, 0 },
{"timeout", 0, POPT_ARG_INT, &io_timeout, 0, 0, 0 },
{"no-timeout", 0, POPT_ARG_VAL, &io_timeout, 0, 0, 0 },
{"contimeout", 0, POPT_ARG_INT, &connect_timeout, 0, 0, 0 },
-@@ -1943,6 +1949,18 @@ void server_options(char **args, int *argc_p)
+@@ -1965,6 +1971,18 @@ void server_options(char **args, int *argc_p)
args[ac++] = "--use-qsort";
if (am_sender) {
return NULL;
}
--static uid_t map_uid(uid_t id, char *name)
+-static uid_t map_uid(uid_t id, const char *name)
-{
- uid_t uid;
- if (id != 0 && name_to_uid(name, &uid))
- return id;
-}
-
--static gid_t map_gid(gid_t id, char *name)
+-static gid_t map_gid(gid_t id, const char *name)
-{
- gid_t gid;
- if (id != 0 && name_to_gid(name, &gid))
}
-/* Add a uid to the list of uids. Only called on receiving side. */
--static struct idlist *recv_add_uid(uid_t id, char *name)
+-static struct idlist *recv_add_uid(uid_t id, const char *name)
+/* Add a uid/gid to its list of ids. Only called on receiving side. */
-+static struct idlist *recv_add_id(struct idlist **idmap_ptr, id_t id, char *name)
++static struct idlist *recv_add_id(struct idlist **idmap_ptr, id_t id, const char *name)
{
- uid_t id2 = name ? map_uid(id, name) : id;
struct idlist *node;
-}
-
-/* Add a gid to the list of gids. Only called on receiving side. */
--static struct idlist *recv_add_gid(gid_t id, char *name)
+-static struct idlist *recv_add_gid(gid_t id, const char *name)
-{
- gid_t id2 = name ? map_gid(id, name) : id;
- struct idlist *node;
}
return node;
-@@ -195,12 +200,9 @@ static struct idlist *recv_add_gid(gid_t id, char *name)
+@@ -195,12 +200,9 @@ static struct idlist *recv_add_gid(gid_t id, const char *name)
/* this function is a definate candidate for a faster algorithm */
uid_t match_uid(uid_t uid)
{
last = list;
}
-@@ -316,7 +321,7 @@ uid_t recv_user_name(int f, uid_t uid)
- if (!name)
- out_of_memory("recv_user_name");
- read_sbuf(f, name, len);
+@@ -320,7 +325,7 @@ uid_t recv_user_name(int f, uid_t uid)
+ free(name);
+ name = NULL;
+ }
- node = recv_add_uid(uid, name); /* node keeps name's memory */
+ node = recv_add_id(&uidmap, uid, name); /* node keeps name's memory */
return node->id2;
}
-@@ -328,7 +333,7 @@ gid_t recv_group_name(int f, gid_t gid, uint16 *flags_ptr)
- if (!name)
- out_of_memory("recv_group_name");
- read_sbuf(f, name, len);
+@@ -336,7 +341,7 @@ gid_t recv_group_name(int f, gid_t gid, uint16 *flags_ptr)
+ free(name);
+ name = NULL;
+ }
- node = recv_add_gid(gid, name); /* node keeps name's memory */
+ node = recv_add_id(&gidmap, gid, name); /* node keeps name's memory */
if (flags_ptr && node->flags & FLAG_SKIP_GROUP)
*flags_ptr |= FLAG_SKIP_GROUP;
return node->id2;
-@@ -355,17 +360,96 @@ void recv_id_list(int f, struct file_list *flist)
+@@ -363,17 +368,93 @@ void recv_id_list(int f, struct file_list *flist)
/* Now convert all the uids/gids from sender values to our values. */
#ifdef SUPPORT_ACLS
+ *--cp = '\0'; /* replace comma */
+ }
+
-+ /* The 0 user/group doesn't get its name sent, or add it explicitly. */
-+ if (numeric_ids)
-+ cp = NULL;
-+ else
-+ cp = usernames ? uid_to_name(0) : gid_to_name(0);
-+ recv_add_id(idmap_ptr, 0, cp);
++ /* The 0 user/group doesn't get its name sent, so add it explicitly. */
++ recv_add_id(idmap_ptr, 0,
++ numeric_ids ? NULL : usernames ? uid_to_name(0) : gid_to_name(0));
+}
diff --git a/compat.c b/compat.c
--- a/compat.c
+++ b/compat.c
-@@ -177,13 +177,6 @@ void setup_protocol(int f_out,int f_in)
+@@ -187,13 +187,6 @@ void setup_protocol(int f_out,int f_in)
if (protocol_version < 30) {
if (append_mode == 1)
append_mode = 2;