version 1.1.1.2, 2013/10/14 07:51:14
|
version 1.1.1.3, 2016/11/01 09:54:32
|
Line 4
|
Line 4
|
* Copyright (C) 1996 Andrew Tridgell |
* Copyright (C) 1996 Andrew Tridgell |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 1996 Paul Mackerras |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2001, 2002 Martin Pool <mbp@samba.org> |
* Copyright (C) 2002-2013 Wayne Davison | * Copyright (C) 2002-2015 Wayne Davison |
* |
* |
* This program is free software; you can redistribute it and/or modify |
* 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 |
* it under the terms of the GNU General Public License as published by |
Line 736 static struct file_struct *recv_file_entry(int f, stru
|
Line 736 static struct file_struct *recv_file_entry(int f, stru
|
} |
} |
#endif |
#endif |
|
|
if (*thisname) | if (*thisname |
clean_fname(thisname, 0); | && (clean_fname(thisname, CFN_REFUSE_DOT_DOT_DIRS) < 0 || (!relative_paths && *thisname == '/'))) { |
| rprintf(FERROR, "ABORTING due to unsafe pathname from sender: %s\n", thisname); |
| exit_cleanup(RERR_PROTOCOL); |
| } |
|
|
if (sanitize_paths) |
if (sanitize_paths) |
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); |
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); |
Line 945 static struct file_struct *recv_file_entry(int f, stru
|
Line 948 static struct file_struct *recv_file_entry(int f, stru
|
memcpy(bp, basename, basename_len); |
memcpy(bp, basename, basename_len); |
|
|
#ifdef SUPPORT_HARD_LINKS |
#ifdef SUPPORT_HARD_LINKS |
if (xflags & XMIT_HLINKED) | if (xflags & XMIT_HLINKED |
| #ifndef CAN_HARDLINK_SYMLINK |
| && !S_ISLNK(mode) |
| #endif |
| #ifndef CAN_HARDLINK_SPECIAL |
| && !IS_SPECIAL(mode) && !IS_DEVICE(mode) |
| #endif |
| ) |
file->flags |= FLAG_HLINKED; |
file->flags |= FLAG_HLINKED; |
#endif |
#endif |
file->modtime = (time_t)modtime; |
file->modtime = (time_t)modtime; |
Line 1156 struct file_struct *make_file(const char *fname, struc
|
Line 1166 struct file_struct *make_file(const char *fname, struc
|
if (sanitize_paths) |
if (sanitize_paths) |
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); |
sanitize_path(thisname, thisname, "", 0, SP_DEFAULT); |
|
|
if (stp && (S_ISDIR(stp->st_mode) || stp->st_mode == 0)) { | if (stp && (S_ISDIR(stp->st_mode) || IS_MISSING_FILE(*stp))) { |
/* This is needed to handle a "symlink/." with a --relative |
/* This is needed to handle a "symlink/." with a --relative |
* dir, or a request to delete a specific file. */ |
* dir, or a request to delete a specific file. */ |
st = *stp; |
st = *stp; |
Line 1200 struct file_struct *make_file(const char *fname, struc
|
Line 1210 struct file_struct *make_file(const char *fname, struc
|
full_fname(thisname)); |
full_fname(thisname)); |
} |
} |
return NULL; |
return NULL; |
} else if (st.st_mode == 0) { | } else if (IS_MISSING_FILE(st)) { |
io_error |= IOERR_GENERAL; |
io_error |= IOERR_GENERAL; |
rprintf(FINFO, "skipping file with bogus (zero) st_mode: %s\n", |
rprintf(FINFO, "skipping file with bogus (zero) st_mode: %s\n", |
full_fname(thisname)); |
full_fname(thisname)); |
Line 1303 struct file_struct *make_file(const char *fname, struc
|
Line 1313 struct file_struct *make_file(const char *fname, struc
|
#endif |
#endif |
|
|
if (always_checksum && am_sender && S_ISREG(st.st_mode)) { |
if (always_checksum && am_sender && S_ISREG(st.st_mode)) { |
file_checksum(thisname, tmp_sum, st.st_size); | file_checksum(thisname, &st, tmp_sum); |
if (sender_keeps_checksum) |
if (sender_keeps_checksum) |
extra_len += SUM_EXTRA_CNT * EXTRA_LEN; |
extra_len += SUM_EXTRA_CNT * EXTRA_LEN; |
} |
} |
Line 2290 struct file_list *send_file_list(int f, int argc, char
|
Line 2300 struct file_list *send_file_list(int f, int argc, char
|
} else |
} else |
fn = p; |
fn = p; |
send_implied_dirs(f, flist, fbuf, fbuf, p, flags, |
send_implied_dirs(f, flist, fbuf, fbuf, p, flags, |
st.st_mode == 0 ? MISSING_NAME : name_type); | IS_MISSING_FILE(st) ? MISSING_NAME : name_type); |
if (fn == p) |
if (fn == p) |
continue; |
continue; |
} |
} |
Line 2425 struct file_list *send_file_list(int f, int argc, char
|
Line 2435 struct file_list *send_file_list(int f, int argc, char
|
return flist; |
return flist; |
} |
} |
|
|
struct file_list *recv_file_list(int f) | struct file_list *recv_file_list(int f, int dir_ndx) |
{ |
{ |
|
const char *good_dirname = NULL; |
struct file_list *flist; |
struct file_list *flist; |
int dstart, flags; |
int dstart, flags; |
int64 start_read; |
int64 start_read; |
Line 2482 struct file_list *recv_file_list(int f)
|
Line 2493 struct file_list *recv_file_list(int f)
|
flist_expand(flist, 1); |
flist_expand(flist, 1); |
file = recv_file_entry(f, flist, flags); |
file = recv_file_entry(f, flist, flags); |
|
|
|
if (inc_recurse) { |
|
static const char empty_dir[] = "\0"; |
|
const char *cur_dir = file->dirname ? file->dirname : empty_dir; |
|
if (relative_paths && *cur_dir == '/') |
|
cur_dir++; |
|
if (cur_dir != good_dirname) { |
|
const char *d = dir_ndx >= 0 ? f_name(dir_flist->files[dir_ndx], NULL) : empty_dir; |
|
if (strcmp(cur_dir, d) != 0) { |
|
rprintf(FERROR, |
|
"ABORTING due to invalid path from sender: %s/%s\n", |
|
cur_dir, file->basename); |
|
exit_cleanup(RERR_PROTOCOL); |
|
} |
|
good_dirname = cur_dir; |
|
} |
|
} |
|
|
if (S_ISREG(file->mode)) { |
if (S_ISREG(file->mode)) { |
/* Already counted */ |
/* Already counted */ |
} else if (S_ISDIR(file->mode)) { |
} else if (S_ISDIR(file->mode)) { |
Line 2553 struct file_list *recv_file_list(int f)
|
Line 2581 struct file_list *recv_file_list(int f)
|
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i()); |
rprintf(FINFO, "[%s] flist_eof=1\n", who_am_i()); |
} |
} |
|
|
|
/* The --relative option sends paths with a leading slash, so we need |
|
* to specify the strip_root option here. We rejected leading slashes |
|
* for a non-relative transfer in recv_file_entry(). */ |
flist_sort_and_clean(flist, relative_paths); |
flist_sort_and_clean(flist, relative_paths); |
|
|
if (protocol_version < 30) { |
if (protocol_version < 30) { |
Line 2602 void recv_additional_file_list(int f)
|
Line 2633 void recv_additional_file_list(int f)
|
rprintf(FINFO, "[%s] receiving flist for dir %d\n", |
rprintf(FINFO, "[%s] receiving flist for dir %d\n", |
who_am_i(), ndx); |
who_am_i(), ndx); |
} |
} |
flist = recv_file_list(f); | flist = recv_file_list(f, ndx); |
flist->parent_ndx = ndx; |
flist->parent_ndx = ndx; |
} |
} |
} |
} |
Line 2656 int flist_find(struct file_list *flist, struct file_st
|
Line 2687 int flist_find(struct file_list *flist, struct file_st
|
high = mid - 1; |
high = mid - 1; |
} |
} |
return -1; |
return -1; |
|
} |
|
|
|
/* Search for a name in the file list. You must specify want_dir_match as: |
|
* 1=match directories, 0=match non-directories, or -1=match either. */ |
|
int flist_find_name(struct file_list *flist, const char *fname, int want_dir_match) |
|
{ |
|
struct { /* We have to create a temporary file_struct for the search. */ |
|
struct file_struct f; |
|
char name_space[MAXPATHLEN]; |
|
} t; |
|
char fbuf[MAXPATHLEN]; |
|
const char *slash = strrchr(fname, '/'); |
|
const char *basename = slash ? slash+1 : fname; |
|
|
|
memset(&t.f, 0, FILE_STRUCT_LEN); |
|
memcpy((void *)t.f.basename, basename, strlen(basename)+1); |
|
|
|
if (slash) { |
|
strlcpy(fbuf, fname, slash - fname + 1); |
|
t.f.dirname = fbuf; |
|
} else |
|
t.f.dirname = NULL; |
|
|
|
t.f.mode = want_dir_match > 0 ? S_IFDIR : S_IFREG; |
|
|
|
if (want_dir_match < 0) |
|
return flist_find_ignore_dirness(flist, &t.f); |
|
return flist_find(flist, &t.f); |
} |
} |
|
|
/* Search for an identically-named item in the file list. Differs from |
/* Search for an identically-named item in the file list. Differs from |