X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/c0dba635ba9d2cf29e39b9363cecc277974d62bb..2cce75453c2961d2e17888cbc196195ae1e70f07:/generator.c diff --git a/generator.c b/generator.c index d6bf4fda..530c2748 100644 --- a/generator.c +++ b/generator.c @@ -317,7 +317,7 @@ static int flush_delete_delay(void) static int remember_delete(struct file_struct *file, const char *fname) { int len; - + while (1) { len = snprintf(deldelay_buf + deldelay_cnt, deldelay_size - deldelay_cnt, @@ -496,7 +496,7 @@ static void do_delete_pass(void) for (j = 0; j < cur_flist->used; j++) { struct file_struct *file = cur_flist->sorted[j]; - if (!(file->flags & FLAG_XFER_DIR)) + if (!(file->flags & FLAG_CONTENT_DIR)) continue; f_name(file, fbuf); @@ -515,7 +515,7 @@ static void do_delete_pass(void) rprintf(FINFO, " \r"); } -int unchanged_attrs(const char *fname, struct file_struct *file, statx *sxp) +int unchanged_attrs(const char *fname, struct file_struct *file, stat_x *sxp) { if (preserve_perms && !BITS_EQUAL(sxp->st.st_mode, file->mode, CHMOD_BITS)) return 0; @@ -547,7 +547,7 @@ int unchanged_attrs(const char *fname, struct file_struct *file, statx *sxp) } void itemize(const char *fnamecmp, struct file_struct *file, int ndx, int statret, - statx *sxp, int32 iflags, uchar fnamecmp_type, + stat_x *sxp, int32 iflags, uchar fnamecmp_type, const char *xname) { if (statret >= 0) { /* A from-dest-dir statret can == 1! */ @@ -562,6 +562,11 @@ 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)) { + ; + } else +#endif if (!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) @@ -825,11 +830,47 @@ static int find_fuzzy(struct file_struct *file, struct file_list *dirlist) return lowest_j; } +/* Copy a file found in our --copy-dest handling. */ +static int copy_altdest_file(const char *src, const char *dest, struct file_struct *file) +{ + char buf[MAXPATHLEN]; + const char *copy_to, *partialptr; + int fd_w; + + if (inplace) { + /* Let copy_file open the destination in place. */ + fd_w = -1; + copy_to = dest; + } else { + fd_w = open_tmpfile(buf, dest, file); + if (fd_w < 0) + return -1; + copy_to = buf; + } + cleanup_set(copy_to, NULL, NULL, -1, -1); + if (copy_file(src, copy_to, fd_w, file->mode, 0) < 0) { + if (verbose) { + rsyserr(FINFO, errno, "copy_file %s => %s", + full_fname(src), copy_to); + } + /* Try to clean up. */ + unlink(copy_to); + cleanup_disable(); + return -1; + } + partialptr = partial_dir ? partial_dir_fname(dest) : NULL; + if (partialptr && *partialptr == '/') + partialptr = NULL; + finish_transfer(dest, copy_to, src, partialptr, file, 1, 0); + cleanup_disable(); + return 0; +} + /* This is only called for regular files. We return -2 if we've finished * handling the file, -1 if no dest-linking occurred, or a non-negative * value if we found an alternate basis file. */ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, - char *cmpbuf, statx *sxp, int itemizing, + char *cmpbuf, stat_x *sxp, int itemizing, enum logcode code) { int best_match = -1; @@ -899,14 +940,8 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, #ifdef SUPPORT_HARD_LINKS try_a_copy: /* Copy the file locally. */ #endif - if (copy_file(cmpbuf, fname, file->mode, 0) < 0) { - if (verbose) { - rsyserr(FINFO, errno, "copy_file %s => %s", - full_fname(cmpbuf), fname); - } + if (!dry_run && copy_altdest_file(cmpbuf, fname, file) < 0) return -1; - } - set_file_attrs(fname, file, NULL, cmpbuf, 0); if (itemizing) itemize(cmpbuf, file, ndx, 0, sxp, ITEM_LOCAL_CHANGE, 0, NULL); #ifdef SUPPORT_XATTRS @@ -934,7 +969,7 @@ static int try_dests_reg(struct file_struct *file, char *fname, int ndx, * handling the file, or -1 if no dest-linking occurred, or a non-negative * value if we found an alternate basis file. */ static int try_dests_non(struct file_struct *file, char *fname, int ndx, - char *cmpbuf, statx *sxp, int itemizing, + char *cmpbuf, stat_x *sxp, int itemizing, enum logcode code) { char lnk[MAXPATHLEN]; @@ -1124,14 +1159,14 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, static int need_fuzzy_dirlist = 0; struct file_struct *fuzzy_file = NULL; int fd = -1, f_copy = -1; - statx sx, real_sx; + stat_x sx, real_sx; STRUCT_STAT partial_st; struct file_struct *back_file = NULL; int statret, real_ret, stat_errno; char *fnamecmp, *partialptr, *backupptr = NULL; char fnamecmpbuf[MAXPATHLEN]; uchar fnamecmp_type; - int implied_dirs_are_missing = relative_paths && !implied_dirs && !inc_recurse; + int implied_dirs_are_missing = relative_paths && !implied_dirs && protocol_version < 30; int del_opts = delete_mode || force_delete ? DEL_RECURSE : 0; if (verbose > 2) @@ -1139,7 +1174,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, if (list_only) { if (S_ISDIR(file->mode) - && ((!implied_dirs && !(file->flags & FLAG_XFER_DIR)) + && ((!implied_dirs && file->flags & FLAG_IMPLIED_DIR) || (inc_recurse && ndx != cur_flist->ndx_start - 1))) return; list_file_entry(file); @@ -1248,10 +1283,10 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } if (S_ISDIR(file->mode)) { - if (!implied_dirs && !(file->flags & FLAG_XFER_DIR)) + if (!implied_dirs && file->flags & FLAG_IMPLIED_DIR) goto cleanup; if (inc_recurse && ndx != cur_flist->ndx_start - 1) { - /* In inc_recurse mode we want ot make sure any missing + /* In inc_recurse mode we want to make sure any missing * directories get created while we're still processing * the parent dir (which allows us to touch the parent * dir's mtime right away). We will handle the dir in @@ -1345,7 +1380,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, } } else if (delete_during && f_out != -1 && !phase && dry_run < 2 - && (file->flags & FLAG_XFER_DIR)) + && (file->flags & FLAG_CONTENT_DIR)) delete_in_dir(fname, file, &real_sx.st.st_dev); goto cleanup; } @@ -1675,7 +1710,7 @@ static void recv_generator(char *fname, struct file_struct *file, int ndx, goto cleanup; if (!(back_file = make_file(fname, NULL, NULL, 0, NO_FILTERS))) goto pretend_missing; - if (copy_file(fname, backupptr, back_file->mode, 1) < 0) { + if (copy_file(fname, backupptr, -1, back_file->mode, 1) < 0) { unmake_file(back_file); back_file = NULL; goto cleanup; @@ -1832,7 +1867,7 @@ static void touch_up_dirs(struct file_list *flist, int ndx) for (i = start; i <= end; i++, counter++) { file = flist->files[i]; if (!S_ISDIR(file->mode) - || (relative_paths && !implied_dirs && !(file->flags & FLAG_XFER_DIR))) + || (!implied_dirs && file->flags & FLAG_IMPLIED_DIR)) continue; if (verbose > 3) { fname = f_name(file, NULL); @@ -1868,6 +1903,7 @@ void check_for_finished_files(int itemizing, enum logcode code, int check_redo) file = flist->files[ndx - flist->ndx_start]; assert(file->flags & FLAG_HLINKED); finish_hard_link(file, f_name(file, fbuf), ndx, NULL, itemizing, code, -1); + flist->in_progress--; } #endif @@ -2002,7 +2038,7 @@ void generate_files(int f_out, const char *local_name) ndx = cur_flist->ndx_start - 1; recv_generator(fbuf, fp, ndx, itemizing, code, f_out); if (delete_during && dry_run < 2) { - if (BITS_SETnUNSET(fp->flags, FLAG_XFER_DIR, FLAG_MISSING_DIR)) { + if (BITS_SETnUNSET(fp->flags, FLAG_CONTENT_DIR, FLAG_MISSING_DIR)) { dev_t dirdev; if (one_file_system) { uint32 *devp = F_DIR_DEV_P(fp);