extern int verbose;
extern int dry_run;
-@@ -646,6 +647,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -645,6 +646,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -1016,6 +1020,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -1015,6 +1019,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;
if (preserve_hard_links && F_IS_HLINKED(file))
finish_hard_link(file, fname, ndx, &sxp->st, itemizing, code, j);
if (!maybe_ATTRS_REPORT && (verbose > 1 || stdout_format_has_i > 1)) {
-@@ -1201,6 +1207,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1200,6 +1206,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)) {
-@@ -1215,14 +1222,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1214,14 +1221,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -2057,7 +2066,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -2056,7 +2065,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
STRUCT_STAT st;
if (link_stat(fname, &st, 0) == 0
&& cmp_time(st.st_mtime, file->modtime) != 0)
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -393,6 +393,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -380,6 +380,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;
-@@ -436,20 +437,38 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -423,20 +424,38 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
set_xattr(fname, file, fnamecmp, sxp);
#endif
}
change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
-@@ -583,7 +602,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -570,7 +589,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)
-@@ -610,7 +629,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -597,7 +616,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL, fnamecmp,
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -97,6 +97,9 @@ extern uid_t our_uid;
+@@ -96,6 +96,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 daemon_filter_list;
-@@ -143,10 +146,15 @@ static void handle_skipped_hlink(struct file_struct *file, int itemizing,
+@@ -142,10 +145,15 @@ static void handle_skipped_hlink(struct file_struct *file, int itemizing,
enum logcode code, int f_out);
#endif
}
/* Delete a file or directory. If DEL_RECURSE is set in the flags, this will
-@@ -194,9 +202,9 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
+@@ -193,9 +201,9 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
if (S_ISDIR(mode)) {
what = "rmdir";
ok = do_rmdir(fbuf) == 0;
+ { RERR_WECRASHED , "rsync caught a CRASH-causing signal" },
{ RERR_WAITCHILD , "waitpid() failed" },
{ RERR_MALLOC , "error allocating core memory buffers" },
- { RERR_PARTIAL , "some files could not be transferred" },
+ { RERR_PARTIAL , "some files/attrs were not transferred (see previous errors)" },
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
-@@ -166,8 +166,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
+@@ -163,8 +163,11 @@ static void wait_process_with_flush(pid_t pid, int *exit_code_ptr)
*exit_code_ptr = RERR_TERMINATED;
else
*exit_code_ptr = RERR_WAITCHILD;
}
/* This function gets called from all 3 processes. We want the client side
-@@ -1320,6 +1323,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
+@@ -1315,6 +1318,14 @@ RETSIGTYPE remember_children(UNUSED(int val))
break;
}
}
}
#endif
#ifndef HAVE_SIGACTION
-@@ -1378,6 +1389,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
+@@ -1373,6 +1384,12 @@ static RETSIGTYPE rsync_panic_handler(UNUSED(int whatsig))
}
#endif
int main(int argc,char *argv[])
{
-@@ -1400,6 +1417,11 @@ int main(int argc,char *argv[])
+@@ -1395,6 +1412,11 @@ int main(int argc,char *argv[])
SIGACTMASK(SIGFPE, rsync_panic_handler);
SIGACTMASK(SIGABRT, rsync_panic_handler);
SIGACTMASK(SIGBUS, rsync_panic_handler);
extern int remove_source_files;
extern int delay_updates;
extern int update_only;
-@@ -713,7 +714,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -712,7 +713,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. */
{
if (st->st_size != F_LENGTH(file))
return 0;
-@@ -722,7 +723,10 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -721,7 +722,10 @@ 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];
return memcmp(sum, F_SUM(file), checksum_len) == 0;
}
-@@ -986,7 +990,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
+@@ -985,7 +989,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx,
match_level = 1;
/* FALL THROUGH */
case 1:
continue;
best_match = j;
match_level = 2;
-@@ -1259,7 +1263,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1258,7 +1262,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
* --ignore-non-existing, daemon exclude, or mkdir failure. */
static struct file_struct *skip_dir = NULL;
static struct file_list *fuzzy_dirlist = NULL;
struct file_struct *fuzzy_file = NULL;
int fd = -1, f_copy = -1;
stat_x sx, real_sx;
-@@ -1348,8 +1352,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1347,8 +1351,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
flist_free(fuzzy_dirlist);
fuzzy_dirlist = NULL;
}
#ifdef SUPPORT_ACLS
if (!preserve_perms)
dflt_perms = default_perms_for_dir(dn);
-@@ -1357,10 +1361,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1356,10 +1360,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
parent_dirname = dn;
}
statret = link_stat(fname, &sx.st, keep_dirlinks && is_dir);
-@@ -1794,7 +1803,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1793,7 +1802,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
;
else if (fnamecmp_type == FNAMECMP_FUZZY)
;
diff --git a/hlink.c b/hlink.c
--- a/hlink.c
+++ b/hlink.c
-@@ -385,7 +385,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
+@@ -386,7 +386,7 @@ int hard_link_check(struct file_struct *file, int ndx, const char *fname,
}
break;
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -115,6 +115,7 @@ static int dir_tweaking;
+@@ -114,6 +114,7 @@ static int dir_tweaking;
static int symlink_timeset_failed_flags;
static int need_retouch_dir_times;
static int need_retouch_dir_perms;
static const char *solo_file = NULL;
/* For calling delete_item() and delete_dir_contents(). */
-@@ -724,7 +725,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
+@@ -723,7 +724,7 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st, int slot
if (always_checksum > 0 && S_ISREG(st->st_mode)) {
char sum[MAX_DIGEST_LEN];
if (checksum_files && slot >= 0)
else
file_checksum(fn, st->st_size, sum);
return memcmp(sum, F_SUM(file), checksum_len) == 0;
-@@ -1367,7 +1368,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1366,7 +1367,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fuzzy_dirlist = get_dirlist(fnamecmpbuf, -1, 1);
}
if (checksum_files) {
}
need_new_dirscan = 0;
}
-@@ -1517,6 +1519,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1516,6 +1518,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
else
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
}
goto cleanup;
}
-@@ -1809,6 +1812,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1808,6 +1811,8 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
handle_partial_dir(partialptr, PDIR_DELETE);
}
set_file_attrs(fname, file, &sx, NULL, maybe_ATTRS_REPORT);
if (itemizing)
itemize(fnamecmp, file, ndx, statret, &sx, 0, 0, NULL);
#ifdef SUPPORT_HARD_LINKS
-@@ -2255,6 +2260,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2249,6 +2254,7 @@ void generate_files(int f_out, const char *local_name)
} else
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
}
for (i = cur_flist->low; i <= cur_flist->high; i++) {
struct file_struct *file = cur_flist->sorted[i];
-@@ -2338,6 +2344,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2332,6 +2338,9 @@ void generate_files(int f_out, const char *local_name)
wait_for_receiver();
}
extern int protocol_version;
extern int remove_source_files;
extern int preserve_hard_links;
-@@ -206,6 +207,9 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
+@@ -203,6 +204,9 @@ static void got_flist_entry_status(enum festatus status, const char *buf)
flist_ndx_push(&hlink_list, ndx);
flist->in_progress++;
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -722,7 +722,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -721,7 +721,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];
extern int preserve_specials;
extern int preserve_hard_links;
extern int preserve_executability;
-@@ -1689,7 +1690,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1688,7 +1689,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
extern int am_root;
extern int am_server;
extern int am_sender;
-@@ -339,7 +340,8 @@ int read_ndx_and_attrs(int f_in, int *iflag_ptr, uchar *type_ptr,
+@@ -326,7 +327,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;
diff --git a/sender.c b/sender.c
--- a/sender.c
+++ b/sender.c
-@@ -315,6 +315,20 @@ void send_files(int f_in, int f_out)
+@@ -309,6 +309,20 @@ void send_files(int f_in, int f_out)
exit_cleanup(RERR_PROTOCOL);
}
extern int preserve_hard_links;
extern int preserve_executability;
extern int preserve_fileflags;
-@@ -621,6 +623,13 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -620,6 +622,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))
-@@ -664,6 +673,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -663,6 +672,12 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
: iflags & (ITEM_TRANSFER|ITEM_LOCAL_CHANGE) && !(iflags & ITEM_MATCHED)
&& (!(iflags & ITEM_XNAME_FOLLOWS) || *xname))
iflags |= ITEM_REPORT_TIME;
#if !defined HAVE_LCHMOD && !defined HAVE_SETATTRLIST
if (S_ISLNK(file->mode)) {
;
-@@ -1224,6 +1239,7 @@ static int try_dests_non(struct file_struct *file, char *fname, int ndx,
+@@ -1223,6 +1238,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)) {
-@@ -1238,14 +1254,16 @@ static void list_file_entry(struct file_struct *f)
+@@ -1237,14 +1253,16 @@ static void list_file_entry(struct file_struct *f)
#ifdef SUPPORT_LINKS
if (preserve_links && S_ISLNK(f->mode)) {
f_name(f, NULL));
}
}
-@@ -1337,6 +1355,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1336,6 +1354,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
return;
}
}
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -485,6 +485,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -472,6 +472,14 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
else
file->flags |= FLAG_TIME_FAILED;
}
change_uid = am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file);
change_gid = gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
-@@ -632,7 +640,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -619,7 +627,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,
ATTRS_DELAY_IMMUTABLE
/* move tmp file over real file */
if (verbose > 2)
-@@ -663,7 +671,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -650,7 +658,7 @@ int finish_transfer(const char *fname, const char *fnametmp,
do_set_file_attrs:
set_file_attrs(fnametmp, file, NULL, fnamecmp,
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -715,6 +716,9 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -714,6 +715,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)
{
extern int append_mode;
extern int make_backups;
extern int csum_length;
-@@ -722,7 +723,8 @@ int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
+@@ -721,7 +722,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];
return memcmp(sum, F_SUM(file), checksum_len) == 0;
}
-@@ -2205,6 +2207,9 @@ void generate_files(int f_out, const char *local_name)
+@@ -2203,6 +2205,9 @@ void generate_files(int f_out, const char *local_name)
: "enabled");
}
extern int file_total;
extern int recurse;
extern int xfer_dirs;
-@@ -76,6 +77,7 @@ extern char *partial_dir;
+@@ -73,6 +74,7 @@ extern char *partial_dir;
extern char *dest_option;
extern char *basis_dir[];
extern char *rsync_path;
extern char *shell_cmd;
extern char *batch_name;
extern char *password_file;
-@@ -1496,6 +1498,9 @@ int main(int argc,char *argv[])
+@@ -1491,6 +1493,9 @@ int main(int argc,char *argv[])
exit_cleanup(RERR_SYNTAX);
}
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -201,7 +201,9 @@ static int fattr_find(struct file_struct *f, char *fname)
+@@ -200,7 +200,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;
-@@ -1986,6 +1988,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1985,6 +1987,21 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
fnamecmp = partialptr;
fnamecmp_type = FNAMECMP_PARTIAL_DIR;
statret = 0;
extern int whole_file;
extern int list_only;
extern int read_batch;
-@@ -99,6 +100,7 @@ extern char *backup_suffix;
+@@ -98,6 +99,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 daemon_filter_list;
int ignore_perishable = 0;
int non_perishable_cnt = 0;
-@@ -106,6 +108,7 @@ int maybe_ATTRS_REPORT = 0;
+@@ -105,6 +107,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;
-@@ -116,7 +119,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_NO_UID_WRITE (1<<0) /* file/dir has our uid w/o write perm */
#define DEL_RECURSE (1<<1) /* if dir, delete all contents */
#define DEL_DIR_IS_EMPTY (1<<2) /* internal delete_FUNCTIONS use only */
-@@ -125,6 +128,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)
-@@ -149,11 +153,121 @@ static int is_backup_file(char *fn)
+@@ -148,11 +152,121 @@ static int is_backup_file(char *fn)
return k > 0 && strcmp(fn+k, backup_suffix) == 0;
}
*/
static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
{
-@@ -187,6 +301,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
+@@ -186,6 +300,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 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;
-@@ -242,6 +358,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
+@@ -241,6 +357,8 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 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, uint16 flags)
{
-@@ -261,7 +379,9 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
+@@ -260,7 +378,9 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
save_filters = push_local_filters(fname, dlen);
non_perishable_cnt = 0;
ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS;
if (!dirlist->used)
-@@ -301,7 +421,8 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
+@@ -300,7 +420,8 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
if (S_ISDIR(fp->mode)) {
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;
}
-@@ -466,13 +587,18 @@ static void do_delayed_deletions(char *delbuf)
+@@ -465,13 +586,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
int save_uid_ndx = uid_ndx;
if (!fbuf) {
-@@ -487,17 +613,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -486,17 +612,22 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
maybe_send_keepalive();
if (io_error && !ignore_errors) {
if (one_file_system) {
if (file->flags & FLAG_TOP_DIR)
filesystem_dev = *fs_dev;
-@@ -510,6 +641,14 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -509,6 +640,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--; ) {
-@@ -522,19 +661,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
+@@ -521,19 +660,28 @@ static void delete_in_dir(char *fbuf, struct file_struct *file, dev_t *fs_dev)
f_name(fp, NULL));
continue;
}
flist_free(dirlist);
if (!save_uid_ndx) {
-@@ -572,9 +720,9 @@ static void do_delete_pass(void)
+@@ -571,9 +719,9 @@ static void do_delete_pass(void)
|| !S_ISDIR(st.st_mode))
continue;
if (do_progress && !am_server)
rprintf(FINFO, " \r");
-@@ -1227,6 +1375,7 @@ static void list_file_entry(struct file_struct *f)
+@@ -1226,6 +1374,7 @@ static void list_file_entry(struct file_struct *f)
}
}
static int phase = 0;
static int dflt_perms;
-@@ -1503,9 +1652,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1502,9 +1651,12 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
}
else if (delete_during && f_out != -1 && !phase
&& !(file->flags & FLAG_MISSING_DIR)) {
change_local_filter_dir(fname, strlen(fname), F_DEPTH(file));
}
goto cleanup;
-@@ -1783,8 +1935,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1782,8 +1934,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;
-@@ -2186,6 +2344,12 @@ void generate_files(int f_out, const char *local_name)
+@@ -2184,6 +2342,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) {
-@@ -2196,7 +2360,7 @@ void generate_files(int f_out, const char *local_name)
+@@ -2194,7 +2358,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",
-@@ -2242,7 +2406,7 @@ void generate_files(int f_out, const char *local_name)
- * error for this directory before we delete in it. */
- while (check_for_io_err && !cur_flist->next)
- wait_for_receiver();
+@@ -2236,7 +2400,7 @@ void generate_files(int f_out, const char *local_name)
+ dirdev = MAKEDEV(DEV_MAJOR(devp), DEV_MINOR(devp));
+ } else
+ dirdev = MAKEDEV(0, 0);
- delete_in_dir(fbuf, fp, &dirdev);
+ delete_in_dir(fbuf, fp, &dirdev, 0);
} else
change_local_filter_dir(fbuf, strlen(fbuf), F_DEPTH(fp));
}
-@@ -2289,7 +2453,21 @@ void generate_files(int f_out, const char *local_name)
+@@ -2283,7 +2447,21 @@ void generate_files(int f_out, const char *local_name)
} while ((cur_flist = cur_flist->next) != NULL);
if (delete_during)
extern int ignore_existing;
extern int ignore_non_existing;
extern int inplace;
-@@ -1724,6 +1725,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1723,6 +1724,13 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
goto cleanup;
}
fnamecmp = fname;
fnamecmp_type = FNAMECMP_FNAME;
-@@ -2096,6 +2104,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -2094,6 +2102,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;
-@@ -2121,6 +2130,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo)
+@@ -2119,6 +2128,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;
diff --git a/generator.c b/generator.c
--- a/generator.c
+++ b/generator.c
-@@ -116,6 +116,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;
extern int uid_ndx;
extern int gid_ndx;
extern int delete_mode;
-@@ -167,7 +169,7 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
+@@ -166,7 +168,7 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
}
if (flags & DEL_NO_UID_WRITE)
if (S_ISDIR(mode) && !(flags & DEL_DIR_IS_EMPTY)) {
int save_uid_ndx = uid_ndx;
-@@ -175,6 +177,13 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
+@@ -174,6 +176,13 @@ static enum delret delete_item(char *fbuf, uint16 mode, uint16 flags)
* delete_dir_contents() always calls us w/DEL_DIR_IS_EMPTY. */
if (!uid_ndx)
uid_ndx = ++file_extra_cnt;
ignore_perishable = 1;
/* If DEL_RECURSE is not set, this just reports emptiness. */
ret = delete_dir_contents(fbuf, flags);
-@@ -295,8 +304,12 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
+@@ -294,8 +303,12 @@ static enum delret delete_dir_contents(char *fname, uint16 flags)
}
strlcpy(p, fp->basename, remainder);
/* Save stack by recursing to ourself directly. */
if (S_ISDIR(fp->mode)) {
if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS)
-@@ -597,6 +610,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
+@@ -596,6 +609,11 @@ int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp)
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
return 0;
if (am_root && uid_ndx && sxp->st.st_uid != (uid_t)F_OWNER(file))
return 0;
-@@ -662,6 +680,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -661,6 +679,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
if (gid_ndx && !(file->flags & FLAG_SKIP_GROUP)
&& sxp->st.st_gid != (gid_t)F_GROUP(file))
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
if (!ACL_READY(*sxp))
-@@ -1440,6 +1463,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1439,6 +1462,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
file->mode = dest_mode(file->mode, sx.st.st_mode,
dflt_perms, statret == 0);
}
if (statret != 0 && basis_dir[0] != NULL) {
int j = try_dests_non(file, fname, ndx, fnamecmpbuf, &sx,
itemizing, code);
-@@ -1480,10 +1507,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1479,10 +1506,15 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
/* We need to ensure that the dirs in the transfer have writable
* permissions during the time we are putting files within them.
* This is then fixed after the transfer is done. */
rsyserr(FERROR_XFER, errno,
"failed to modify permissions on %s",
full_fname(fname));
-@@ -1518,6 +1550,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1517,6 +1549,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
file->mode = dest_mode(file->mode, sx.st.st_mode, dflt_perms,
exists);
}
#ifdef SUPPORT_HARD_LINKS
if (preserve_hard_links && F_HLINK_NOT_FIRST(file)
-@@ -2052,13 +2088,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
+@@ -2051,13 +2087,17 @@ static void touch_up_dirs(struct file_list *flist, int ndx)
continue;
fname = f_name(file, NULL);
if (!(file->mode & S_IWUSR))
extern int preserve_executability;
extern int preserve_times;
extern int am_root;
-@@ -387,6 +388,39 @@ mode_t dest_mode(mode_t flist_mode, mode_t stat_mode, int dflt_perms,
+@@ -374,6 +375,39 @@ 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)
{
-@@ -440,7 +474,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -427,7 +461,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
flags |= ATTRS_SKIP_MTIME;
if (!(flags & ATTRS_SKIP_MTIME)
&& cmp_time(sxp->st.st_mtime, file->modtime) != 0) {
if (ret < 0) {
rsyserr(FERROR_XFER, errno, "failed to set times on %s",
full_fname(fname));
-@@ -476,7 +510,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -463,7 +497,8 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
if (am_root >= 0) {
if (do_lchown(fname,
change_uid ? (uid_t)F_OWNER(file) : sxp->st.st_uid,
/* We shouldn't have attempted to change uid
* or gid unless have the privilege. */
rsyserr(FERROR_XFER, errno, "%s %s failed",
-@@ -508,7 +543,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -495,7 +530,7 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
#ifdef HAVE_CHMOD
if (!BITS_EQUAL(sxp->st.st_mode, new_mode, CHMOD_BITS)) {
if (ret < 0) {
rsyserr(FERROR_XFER, errno,
"failed to set permissions on %s",
-@@ -520,6 +555,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -507,6 +542,19 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
}
#endif
if (verbose > 1 && flags & ATTRS_REPORT) {
if (updated)
rprintf(FCLIENT, "%s\n", fname);
-@@ -583,7 +631,8 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -570,7 +618,8 @@ 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)
-@@ -602,6 +651,10 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -589,6 +638,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. */
diff --git a/rsync.c b/rsync.c
--- a/rsync.c
+++ b/rsync.c
-@@ -50,6 +50,7 @@ extern int keep_dirlinks;
+@@ -48,6 +48,7 @@ extern int inplace;
+ extern int flist_eof;
+ extern int keep_dirlinks;
extern int make_backups;
- extern int delete_during;
- extern int check_for_io_err;
+extern char *link_by_hash_dir;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
extern struct chmod_mode_struct *daemon_chmod_modes;
#ifdef ICONV_OPTION
-@@ -588,8 +589,15 @@ int finish_transfer(const char *fname, const char *fnametmp,
+@@ -575,8 +576,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);
extern int remove_source_files;
extern int need_messages_from_generator;
extern int kluge_around_eof;
-@@ -71,6 +72,8 @@ extern int check_for_io_err;
+@@ -68,6 +69,8 @@ extern int connect_timeout;
extern pid_t cleanup_child_pid;
extern unsigned int module_dirlen;
extern struct stats stats;
extern char *filesfrom_host;
extern char *partial_dir;
extern char *dest_option;
-@@ -88,6 +91,7 @@ int local_server = 0;
+@@ -85,6 +88,7 @@ int local_server = 0;
int daemon_over_rsh = 0;
mode_t orig_umask = 0;
int batch_gen_fd = -1;
/* There's probably never more than at most 2 outstanding child processes,
* but set it higher, just in case. */
-@@ -1008,6 +1012,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
+@@ -1003,6 +1007,12 @@ int client_run(int f_in, int f_out, pid_t pid, int argc, char *argv[])
if (am_sender) {
keep_dirlinks = 0; /* Must be disabled on the sender. */
extern int uid_ndx;
extern int gid_ndx;
extern int delete_mode;
-@@ -628,6 +629,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -627,6 +628,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
const char *xname)
{
if (statret >= 0) { /* A from-dest-dir statret can == 1! */
int keep_time = !preserve_times ? 0
: S_ISDIR(file->mode) ? preserve_times > 1 :
#if defined HAVE_LUTIMES && defined HAVE_UTIMES
-@@ -657,10 +659,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -656,10 +658,11 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
} else if (preserve_executability
&& ((sxp->st.st_mode & 0111 ? 1 : 0) ^ (file->mode & 0111 ? 1 : 0)))
iflags |= ITEM_REPORT_PERMS;
iflags |= ITEM_REPORT_GROUP;
#ifdef SUPPORT_ACLS
if (preserve_acls && !S_ISLNK(file->mode)) {
-@@ -1436,7 +1439,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
+@@ -1435,7 +1438,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx,
real_sx = sx;
if (file->flags & FLAG_DIR_CREATED)
statret = -1;
extern int am_root;
extern int am_server;
extern int am_sender;
-@@ -452,9 +453,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
+@@ -439,9 +440,11 @@ int set_file_attrs(const char *fname, struct file_struct *file, stat_x *sxp,
file->flags |= FLAG_TIME_FAILED;
}
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
-@@ -1126,6 +1126,18 @@ static int start_client(int argc, char *argv[])
+@@ -1121,6 +1121,18 @@ static int start_client(int argc, char *argv[])
if (!read_batch) { /* for read_batch, NO source is specified */
char *path = check_for_hostspec(argv[0], &shell_machine, &rsync_port);
if (!remove_source_files)
return;
-@@ -139,7 +141,11 @@ void successful_send(int ndx)
+@@ -133,7 +135,11 @@ void successful_send(int ndx)
return;
f_name(file, fname);
extern int size_only;
extern OFF_T max_size;
extern OFF_T min_size;
-@@ -715,7 +716,7 @@ void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statre
+@@ -714,7 +715,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)
{
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
-@@ -139,7 +139,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
+@@ -136,7 +136,7 @@ pid_t wait_process(pid_t pid, int *status_ptr, int flags)
}
/* Wait for a process to exit, calling io_flush while waiting. */
extern struct stats stats;
extern struct file_list *cur_flist, *first_flist, *dir_flist;
-@@ -181,6 +182,26 @@ void send_files(int f_in, int f_out)
+@@ -175,6 +176,26 @@ void send_files(int f_in, int f_out)
enum logcode log_code = log_before_transfer ? FLOG : FINFO;
int f_xfer = write_batch < 0 ? batch_fd : f_out;
int ndx, j;
if (verbose > 2)
rprintf(FINFO, "send_files starting\n");
-@@ -285,6 +306,7 @@ void send_files(int f_in, int f_out)
+@@ -279,6 +300,7 @@ void send_files(int f_in, int f_out)
exit_cleanup(RERR_PROTOCOL);
}
fd = do_open(fname, O_RDONLY, 0);
if (fd == -1) {
if (errno == ENOENT) {
-@@ -306,6 +328,33 @@ void send_files(int f_in, int f_out)
+@@ -300,6 +322,33 @@ void send_files(int f_in, int f_out)
continue;
}
/* map the local file */
if (do_fstat(fd, &st) != 0) {
io_error |= IOERR_GENERAL;
-@@ -356,6 +405,8 @@ void send_files(int f_in, int f_out)
+@@ -350,6 +399,8 @@ void send_files(int f_in, int f_out)
}
}
close(fd);
extern struct file_list *cur_flist;
#ifdef ICONV_OPTION
extern int filesfrom_convert;
-@@ -222,16 +223,24 @@ static void check_timeout(void)
+@@ -219,16 +220,24 @@ static void check_timeout(void)
{
time_t t;