extern int preserve_specials;
extern int delete_during;
extern int missing_args;
-extern int uid_ndx;
-extern int gid_ndx;
extern int eol_nulls;
extern int relative_paths;
extern int implied_dirs;
-extern int file_extra_cnt;
extern int ignore_perishable;
extern int non_perishable_cnt;
extern int prune_empty_dirs;
extern int output_needs_newline;
extern int sender_keeps_checksum;
extern int unsort_ndx;
+extern uid_t our_uid;
extern struct stats stats;
extern char *filesfrom_host;
extern char *usermap, *groupmap;
extern iconv_t ic_send, ic_recv;
#endif
-#ifdef HAVE_UTIMENSAT
-#ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
-#define ST_MTIME_NSEC st_mtim.tv_nsec
-#elif defined(HAVE_STRUCT_STAT_ST_MTIMENSEC)
-#define ST_MTIME_NSEC st_mtimensec
-#endif
-#endif
-
#define PTR_SIZE (sizeof (struct file_struct *))
int io_error;
#define NORMAL_NAME 0
#define SLASH_ENDING_NAME 1
#define DOTDIR_NAME 2
+#define MISSING_NAME 3
/* Starting from protocol version 26, we always use 64-bit ino_t and dev_t
* internally, even if this platform does not allow files to have 64-bit inums.
}
#endif
file->mode = st.st_mode;
- if (uid_ndx) /* Check uid_ndx instead of preserve_uid for del support */
+ if (preserve_uid)
F_OWNER(file) = st.st_uid;
- if (gid_ndx) /* Check gid_ndx instead of preserve_gid for del support */
+ if (preserve_gid)
F_GROUP(file) = st.st_gid;
+ if (am_generator && st.st_uid == our_uid)
+ file->flags |= FLAG_OWNED_BY_US;
if (basename != thisname)
file->dirname = lastdir;
remainder = 0;
for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) {
+ unsigned name_len;
char *dname = d_name(di);
if (dname[0] == '.' && (dname[1] == '\0'
|| (dname[1] == '.' && dname[2] == '\0')))
continue;
- unsigned name_len = strlcpy(p, dname, remainder);
+ name_len = strlcpy(p, dname, remainder);
if (name_len >= remainder) {
char save = fbuf[len];
fbuf[len] = '\0';
if (name_type != NORMAL_NAME) {
STRUCT_STAT st;
- if (link_stat(fbuf, &st, 1) != 0) {
+ if (name_type == MISSING_NAME)
+ memset(&st, 0, sizeof st);
+ else if (link_stat(fbuf, &st, 1) != 0) {
interpret_stat_error(fbuf, True);
continue;
}
fn = fbuf;
/* A leading ./ can be used in relative mode to affect
* the dest dir without its name being in the path. */
- if (*fn == '.' && fn[1] == '/' && !implied_dot_dir) {
- send_file_name(f, flist, ".", NULL,
- (flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR,
- ALL_FILTERS);
- implied_dot_dir = 1;
- }
+ if (*fn == '.' && fn[1] == '/' && fn[2] && !implied_dot_dir)
+ implied_dot_dir = -1;
len = clean_fname(fn, CFN_KEEP_TRAILING_SLASH
| CFN_DROP_TRAILING_DOT_DIR);
if (len == 1) {
dirlen = dir ? strlen(dir) : 0;
if (dirlen != lastdir_len || memcmp(lastdir, dir, dirlen) != 0) {
if (!change_pathname(NULL, dir, -dirlen))
- continue;
+ goto bad_path;
lastdir = pathname;
lastdir_len = pathname_len;
- } else if (!change_pathname(NULL, lastdir, lastdir_len))
+ } else if (!change_pathname(NULL, lastdir, lastdir_len)) {
+ bad_path:
+ if (implied_dot_dir < 0)
+ implied_dot_dir = 0;
continue;
+ }
+
+ if (implied_dot_dir < 0) {
+ implied_dot_dir = 1;
+ send_file_name(f, flist, ".", NULL, (flags | FLAG_IMPLIED_DIR) & ~FLAG_CONTENT_DIR, ALL_FILTERS);
+ }
if (fn != fbuf)
memmove(fbuf, fn, len + 1);
p = fn;
} else
fn = p;
- send_implied_dirs(f, flist, fbuf, fbuf, p, flags, name_type);
+ send_implied_dirs(f, flist, fbuf, fbuf, p, flags,
+ st.st_mode == 0 ? MISSING_NAME : name_type);
if (fn == p)
continue;
}
* of the dirname string, and also indicates that "dirname" is a MAXPATHLEN
* buffer (the functions we call will append names onto the end, but the old
* dir value will be restored on exit). */
-struct file_list *get_dirlist(char *dirname, int dlen, int ignore_filter_rules)
+struct file_list *get_dirlist(char *dirname, int dlen, int flags)
{
struct file_list *dirlist;
char dirbuf[MAXPATHLEN];
int save_recurse = recurse;
int save_xfer_dirs = xfer_dirs;
int save_prune_empty_dirs = prune_empty_dirs;
+ int senddir_fd = flags & GDL_IGNORE_FILTER_RULES ? -2 : -1;
if (dlen < 0) {
dlen = strlcpy(dirbuf, dirname, MAXPATHLEN);
recurse = 0;
xfer_dirs = 1;
- send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
+ send_directory(senddir_fd, dirlist, dirname, dlen, FLAG_CONTENT_DIR);
xfer_dirs = save_xfer_dirs;
recurse = save_recurse;
if (INFO_GTE(PROGRESS, 1))