X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/e366e5303fa25e3d007691109293901ad7a7b6f6..b3bf9b9df95137a3a43248be9599d919b04877af:/flist.c diff --git a/flist.c b/flist.c index cb667aa1..2e449c0b 100644 --- a/flist.c +++ b/flist.c @@ -4,7 +4,7 @@ * Copyright (C) 1996 Andrew Tridgell * Copyright (C) 1996 Paul Mackerras * Copyright (C) 2001, 2002 Martin Pool - * Copyright (C) 2002-2008 Wayne Davison + * Copyright (C) 2002-2009 Wayne Davison * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -72,6 +72,7 @@ extern int sender_keeps_checksum; extern int unsort_ndx; extern struct stats stats; extern char *filesfrom_host; +extern char *usermap, *groupmap; extern char curr_dir[MAXPATHLEN]; @@ -802,7 +803,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, uid = (uid_t)read_varint(f); if (xflags & XMIT_USER_NAME_FOLLOWS) uid = recv_user_name(f, uid); - else if (inc_recurse && am_root && !numeric_ids) + else if (inc_recurse && am_root && (!numeric_ids || usermap)) uid = match_uid(uid); } } @@ -814,7 +815,7 @@ static struct file_struct *recv_file_entry(struct file_list *flist, gid_flags = 0; if (xflags & XMIT_GROUP_NAME_FOLLOWS) gid = recv_group_name(f, gid, &gid_flags); - else if (inc_recurse && (!am_root || !numeric_ids)) + else if (inc_recurse && (!am_root || !numeric_ids || groupmap)) gid = match_gid(gid, &gid_flags); } } @@ -1332,25 +1333,6 @@ struct file_struct *make_file(const char *fname, struct file_list *flist, else if (!pool) F_DEPTH(file) = extra_len / EXTRA_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) { - STRUCT_STAT st2; - int save_mode = file->mode; - file->mode = S_IFDIR; /* Find a directory with our name. */ - if (flist_find(dir_flist, file) >= 0 - && x_stat(thisname, &st2, NULL) == 0 && S_ISDIR(st2.st_mode)) { - file->modtime = st2.st_mtime; - file->len32 = 0; - file->mode = st2.st_mode; - if (uid_ndx) - F_OWNER(file) = st2.st_uid; - if (gid_ndx) - F_GROUP(file) = st2.st_gid; - } else - file->mode = save_mode; - } - if (basename_len == 0+1) { if (!pool) unmake_file(file); @@ -1396,6 +1378,7 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, #endif #if defined SUPPORT_ACLS || defined SUPPORT_XATTRS stat_x sx; + init_stat_x(&sx); #endif #ifdef SUPPORT_LINKS @@ -1459,7 +1442,6 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, #ifdef SUPPORT_ACLS if (preserve_acls && !S_ISLNK(file->mode)) { sx.st.st_mode = file->mode; - sx.acc_acl = sx.def_acl = NULL; if (get_acl(fname, &sx) < 0) { io_error |= IOERR_GENERAL; return NULL; @@ -1468,7 +1450,6 @@ static struct file_struct *send_file_name(int f, struct file_list *flist, #endif #ifdef SUPPORT_XATTRS if (preserve_xattrs) { - sx.xattr = NULL; if (get_xattr(fname, &sx) < 0) { io_error |= IOERR_GENERAL; return NULL; @@ -1657,6 +1638,8 @@ static void send_directory(int f, struct file_list *flist, char *fbuf, int len, assert(flist != NULL); if (!(d = opendir(fbuf))) { + if (errno == ENOENT) + return; io_error |= IOERR_GENERAL; rsyserr(FERROR_XFER, errno, "opendir %s failed", full_fname(fbuf)); return; @@ -2008,9 +1991,6 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) start_write = stats.total_written; gettimeofday(&start_tv, NULL); - if (!orig_dir) - orig_dir = strdup(curr_dir); - if (relative_paths && protocol_version >= 30) implied_dirs = 1; /* We send flagged implied dirs */ @@ -2036,6 +2016,9 @@ struct file_list *send_file_list(int f, int argc, char *argv[]) use_ff_fd = 1; } + if (!orig_dir) + orig_dir = strdup(curr_dir); + while (1) { char fbuf[MAXPATHLEN], *fn, name_type; @@ -2322,6 +2305,10 @@ struct file_list *recv_file_list(int f) else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server) rprintf(FCLIENT, "receiving incremental file list\n"); rprintf(FLOG, "receiving file list\n"); + if (usermap) + parse_name_map(usermap, True); + if (groupmap) + parse_name_map(groupmap, False); } start_read = stats.total_read; @@ -2533,6 +2520,28 @@ int flist_find(struct file_list *flist, struct file_struct *f) return -1; } +/* Search for an identically-named item in the file list. Differs from + * flist_find in that an item that agrees with "f" in directory-ness is + * preferred but one that does not is still found. */ +int flist_find_ignore_dirness(struct file_list *flist, struct file_struct *f) +{ + mode_t save_mode; + int ndx; + + /* First look for an item that agrees in directory-ness. */ + ndx = flist_find(flist, f); + if (ndx >= 0) + return ndx; + + /* Temporarily flip f->mode to look for an item of opposite + * directory-ness. */ + save_mode = f->mode; + f->mode = S_ISDIR(f->mode) ? S_IFREG : S_IFDIR; + ndx = flist_find(flist, f); + f->mode = save_mode; + return ndx; +} + /* * Free up any resources a file_struct has allocated * and clear the file.