列挙型 | |
enum | fnc_state { s_DIR, s_SLASH, s_BASE, s_TRAILING } |
enum | fnc_type { t_PATH, t_ITEM } |
関数 | |
static void | clean_flist (struct file_list *flist, int strip_root, int no_dups) |
static void | output_flist (struct file_list *flist) |
void | init_flist (void) |
static int | show_filelist_p (void) |
static void | start_filelist_progress (char *kind) |
static void | emit_filelist_progress (int count) |
static void | maybe_emit_filelist_progress (int count) |
static void | finish_filelist_progress (const struct file_list *flist) |
void | show_flist_stats (void) |
static void | list_file_entry (struct file_struct *f) |
static int | readlink_stat (const char *path, STRUCT_STAT *buffer, char *linkbuf) |
Stat either a symlink or its referent, depending on the settings of copy_links, copy_unsafe_links, etc. | |
int | link_stat (const char *path, STRUCT_STAT *buffer, int follow_dirlinks) |
static int | is_excluded (char *fname, int is_dir, int filter_level) |
static int | to_wire_mode (mode_t mode) |
static mode_t | from_wire_mode (int mode) |
static void | send_directory (int f, struct file_list *flist, char *fbuf, int len) |
void | flist_expand (struct file_list *flist) |
Make sure flist is big enough to hold at least flist->count entries. | |
static void | send_file_entry (struct file_struct *file, int f) |
static struct file_struct * | receive_file_entry (struct file_list *flist, unsigned short flags, int f) |
file_struct * | make_file (char *fname, struct file_list *flist, STRUCT_STAT *stp, unsigned short flags, int filter_level) |
Create a file_struct for a named file by reading its stat() information and performing extensive checks against global options. | |
static struct file_struct * | send_file_name (int f, struct file_list *flist, char *fname, STRUCT_STAT *stp, unsigned short flags) |
static void | send_if_directory (int f, struct file_list *flist, struct file_struct *file, char *fbuf, unsigned int ol) |
file_list * | send_file_list (int f, int argc, char *argv[]) |
file_list * | recv_file_list (int f) |
static int | file_compare (struct file_struct **file1, struct file_struct **file2) |
int | flist_find (struct file_list *flist, struct file_struct *f) |
void | clear_file (struct file_struct *file, struct file_list *flist) |
file_list * | flist_new (int with_hlink, char *msg) |
void | flist_free (struct file_list *flist) |
int | f_name_cmp (struct file_struct *f1, struct file_struct *f2) |
char * | f_name (struct file_struct *f, char *fbuf) |
file_list * | get_dirlist (char *dirname, int dlen, int ignore_filter_rules) |
変数 | |
int | verbose |
int | list_only |
int | am_root |
int | am_server |
int | am_daemon |
int | am_sender |
int | do_progress |
int | always_checksum |
int | module_id |
int | ignore_errors |
int | numeric_ids |
int | recurse |
int | xfer_dirs |
int | filesfrom_fd |
int | one_file_system |
int | copy_dirlinks |
int | keep_dirlinks |
int | preserve_acls |
int | preserve_xattrs |
int | preserve_links |
int | preserve_hard_links |
int | preserve_devices |
int | preserve_specials |
int | preserve_uid |
int | preserve_gid |
int | relative_paths |
int | implied_dirs |
int | prune_empty_dirs |
int | copy_links |
int | copy_unsafe_links |
int | protocol_version |
int | sanitize_paths |
stats | stats |
file_list * | the_file_list |
char | curr_dir [MAXPATHLEN] |
chmod_mode_struct * | chmod_modes |
filter_list_struct | filter_list |
filter_list_struct | server_filter_list |
int | io_error |
int | checksum_len |
dev_t | filesystem_dev |
unsigned int | file_struct_len |
static char | empty_sum [MD4_SUM_LENGTH] |
static int | flist_count_offset |
static char * | flist_dir |
static int | flist_dir_len |
flist.c で定義されています。
enum fnc_state |
static void clean_flist | ( | struct file_list * | flist, | |
int | strip_root, | |||
int | no_dups | |||
) | [static] |
参照先 am_server・file_struct::basename・clear_file()・file_list::count・file_struct::depth・file_struct::dir・file_struct::dirname・f_name()・f_name_cmp()・file_compare()・file_list::files・FINFO・file_struct::flags・flist_find()・file_list::high・is_excluded()・file_list::low・file_struct::mode・protocol_version・prune_empty_dirs・rprintf()・verbose.
参照元 get_dirlist()・recv_file_list()・send_file_list().
01580 { 01581 char fbuf[MAXPATHLEN]; 01582 int i, prev_i = 0; 01583 01584 if (!flist) 01585 return; 01586 if (flist->count == 0) { 01587 flist->high = -1; 01588 return; 01589 } 01590 01591 qsort(flist->files, flist->count, 01592 sizeof flist->files[0], (int (*)())file_compare); 01593 01594 for (i = no_dups? 0 : flist->count; i < flist->count; i++) { 01595 if (flist->files[i]->basename) { 01596 prev_i = i; 01597 break; 01598 } 01599 } 01600 flist->low = prev_i; 01601 while (++i < flist->count) { 01602 int j; 01603 struct file_struct *file = flist->files[i]; 01604 01605 if (!file->basename) 01606 continue; 01607 if (f_name_cmp(file, flist->files[prev_i]) == 0) 01608 j = prev_i; 01609 else if (protocol_version >= 29 && S_ISDIR(file->mode)) { 01610 int save_mode = file->mode; 01611 /* Make sure that this directory doesn't duplicate a 01612 * non-directory earlier in the list. */ 01613 flist->high = prev_i; 01614 file->mode = S_IFREG; 01615 j = flist_find(flist, file); 01616 file->mode = save_mode; 01617 } else 01618 j = -1; 01619 if (j >= 0) { 01620 struct file_struct *fp = flist->files[j]; 01621 int keep, drop; 01622 /* If one is a dir and the other is not, we want to 01623 * keep the dir because it might have contents in the 01624 * list. */ 01625 if (S_ISDIR(file->mode) != S_ISDIR(fp->mode)) { 01626 if (S_ISDIR(file->mode)) 01627 keep = i, drop = j; 01628 else 01629 keep = j, drop = i; 01630 } else 01631 keep = j, drop = i; 01632 if (verbose > 1 && !am_server) { 01633 rprintf(FINFO, 01634 "removing duplicate name %s from file list (%d)\n", 01635 f_name(file, fbuf), drop); 01636 } 01637 /* Make sure we don't lose track of a user-specified 01638 * top directory. */ 01639 flist->files[keep]->flags |= flist->files[drop]->flags 01640 & (FLAG_TOP_DIR|FLAG_DEL_HERE); 01641 01642 clear_file(flist->files[drop], flist); 01643 01644 if (keep == i) { 01645 if (flist->low == drop) { 01646 for (j = drop + 1; 01647 j < i && !flist->files[j]->basename; 01648 j++) {} 01649 flist->low = j; 01650 } 01651 prev_i = i; 01652 } 01653 } else 01654 prev_i = i; 01655 } 01656 flist->high = no_dups ? prev_i : flist->count - 1; 01657 01658 if (strip_root) { 01659 /* We need to strip off the leading slashes for relative 01660 * paths, but this must be done _after_ the sorting phase. */ 01661 for (i = flist->low; i <= flist->high; i++) { 01662 struct file_struct *file = flist->files[i]; 01663 01664 if (!file->dirname) 01665 continue; 01666 while (*file->dirname == '/') 01667 file->dirname++; 01668 if (!*file->dirname) 01669 file->dirname = NULL; 01670 } 01671 } 01672 01673 if (prune_empty_dirs && no_dups) { 01674 int j, prev_depth = 0; 01675 01676 prev_i = 0; /* It's OK that this isn't really true. */ 01677 01678 for (i = flist->low; i <= flist->high; i++) { 01679 struct file_struct *fp, *file = flist->files[i]; 01680 01681 /* This temporarily abuses the dir.depth value for a 01682 * directory that is in a chain that might get pruned. 01683 * We restore the old value if it gets a reprieve. */ 01684 if (S_ISDIR(file->mode) && file->dir.depth) { 01685 /* Dump empty dirs when coming back down. */ 01686 for (j = prev_depth; j >= file->dir.depth; j--) { 01687 fp = flist->files[prev_i]; 01688 if (fp->dir.depth >= 0) 01689 break; 01690 prev_i = -fp->dir.depth-1; 01691 clear_file(fp, flist); 01692 } 01693 prev_depth = file->dir.depth; 01694 if (is_excluded(f_name(file, fbuf), 1, 01695 ALL_FILTERS)) { 01696 /* Keep dirs through this dir. */ 01697 for (j = prev_depth-1; ; j--) { 01698 fp = flist->files[prev_i]; 01699 if (fp->dir.depth >= 0) 01700 break; 01701 prev_i = -fp->dir.depth-1; 01702 fp->dir.depth = j; 01703 } 01704 } else 01705 file->dir.depth = -prev_i-1; 01706 prev_i = i; 01707 } else { 01708 /* Keep dirs through this non-dir. */ 01709 for (j = prev_depth; ; j--) { 01710 fp = flist->files[prev_i]; 01711 if (fp->dir.depth >= 0) 01712 break; 01713 prev_i = -fp->dir.depth-1; 01714 fp->dir.depth = j; 01715 } 01716 } 01717 } 01718 /* Dump empty all remaining empty dirs. */ 01719 while (1) { 01720 struct file_struct *fp = flist->files[prev_i]; 01721 if (fp->dir.depth >= 0) 01722 break; 01723 prev_i = -fp->dir.depth-1; 01724 clear_file(fp, flist); 01725 } 01726 01727 for (i = flist->low; i <= flist->high; i++) { 01728 if (flist->files[i]->basename) 01729 break; 01730 } 01731 flist->low = i; 01732 for (i = flist->high; i >= flist->low; i--) { 01733 if (flist->files[i]->basename) 01734 break; 01735 } 01736 flist->high = i; 01737 } 01738 }
static void output_flist | ( | struct file_list * | flist | ) | [static] |
参照先 am_root・am_sender・file_struct::basename・file_list::count・file_struct::depth・file_struct::dir・file_struct::dirname・file_list::files・FINFO・file_struct::flags・file_struct::gid・file_struct::length・file_struct::mode・preserve_gid・preserve_uid・file_struct::root・rprintf()・sprintf()・file_struct::uid・who_am_i().
参照元 get_dirlist()・recv_file_list()・send_file_list().
01741 { 01742 char uidbuf[16], gidbuf[16], depthbuf[16]; 01743 struct file_struct *file; 01744 const char *who = who_am_i(); 01745 int i; 01746 01747 for (i = 0; i < flist->count; i++) { 01748 file = flist->files[i]; 01749 if ((am_root || am_sender) && preserve_uid) 01750 sprintf(uidbuf, " uid=%ld", (long)file->uid); 01751 else 01752 *uidbuf = '\0'; 01753 if (preserve_gid && file->gid != GID_NONE) 01754 sprintf(gidbuf, " gid=%ld", (long)file->gid); 01755 else 01756 *gidbuf = '\0'; 01757 if (!am_sender) 01758 sprintf(depthbuf, "%d", file->dir.depth); 01759 rprintf(FINFO, "[%s] i=%d %s %s%s%s%s mode=0%o len=%.0f%s%s flags=%x\n", 01760 who, i, am_sender ? NS(file->dir.root) : depthbuf, 01761 file->dirname ? file->dirname : "", 01762 file->dirname ? "/" : "", NS(file->basename), 01763 S_ISDIR(file->mode) ? "/" : "", (int)file->mode, 01764 (double)file->length, uidbuf, gidbuf, file->flags); 01765 } 01766 }
void init_flist | ( | void | ) |
参照先 checksum_len・file_struct_len・file_struct::flags・protocol_version.
参照元 main().
00084 { 00085 struct file_struct f; 00086 00087 /* Figure out how big the file_struct is without trailing padding */ 00088 file_struct_len = offsetof(struct file_struct, flags) + sizeof f.flags; 00089 checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH; 00090 }
static int show_filelist_p | ( | void | ) | [static] |
static void start_filelist_progress | ( | char * | kind | ) | [static] |
参照先 do_progress・FINFO・rflush()・rprintf()・verbose.
参照元 recv_file_list()・send_file_list().
00098 { 00099 rprintf(FINFO, "%s ... ", kind); 00100 if (verbose > 1 || do_progress) 00101 rprintf(FINFO, "\n"); 00102 rflush(FINFO); 00103 }
static void emit_filelist_progress | ( | int | count | ) | [static] |
static void maybe_emit_filelist_progress | ( | int | count | ) | [static] |
参照先 do_progress・emit_filelist_progress()・show_filelist_p().
参照元 recv_file_list()・send_file_name().
00111 { 00112 if (do_progress && show_filelist_p() && (count % 100) == 0) 00113 emit_filelist_progress(count); 00114 }
static void finish_filelist_progress | ( | const struct file_list * | flist | ) | [static] |
参照先 file_list::count・do_progress・FINFO・rprintf().
参照元 recv_file_list()・send_file_list().
00117 { 00118 if (do_progress) { 00119 /* This overwrites the progress line */ 00120 rprintf(FINFO, "%d file%sto consider\n", 00121 flist->count, flist->count == 1 ? " " : "s "); 00122 } else 00123 rprintf(FINFO, "done\n"); 00124 }
void show_flist_stats | ( | void | ) |
static void list_file_entry | ( | struct file_struct * | f | ) | [static] |
参照先 file_struct::basename・f_name()・FINFO・file_struct::length・file_struct::link・file_struct::mode・file_struct::modtime・permstring()・preserve_links・rprintf()・timestring()・file_struct::u.
参照元 recv_file_list().
00132 { 00133 char permbuf[PERMSTRING_SIZE]; 00134 00135 if (!f->basename) { 00136 /* this can happen if duplicate names were removed */ 00137 return; 00138 } 00139 00140 permstring(permbuf, f->mode); 00141 00142 #ifdef SUPPORT_LINKS 00143 if (preserve_links && S_ISLNK(f->mode)) { 00144 rprintf(FINFO, "%s %11.0f %s %s -> %s\n", 00145 permbuf, 00146 (double)f->length, timestring(f->modtime), 00147 f_name(f, NULL), f->u.link); 00148 } else 00149 #endif 00150 { 00151 rprintf(FINFO, "%s %11.0f %s %s\n", 00152 permbuf, 00153 (double)f->length, timestring(f->modtime), 00154 f_name(f, NULL)); 00155 } 00156 }
static int readlink_stat | ( | const char * | path, | |
STRUCT_STAT * | buffer, | |||
char * | linkbuf | |||
) | [static] |
Stat either a symlink or its referent, depending on the settings of copy_links, copy_unsafe_links, etc.
-1 | on error | |
0 | for success |
path
is a symlink, then linkbuf
(of size MAXPATHLEN
) contains the symlink target.
buffer
contains information about the link or the referrent as appropriate, if they exist.
参照先 copy_dirlinks・copy_links・copy_unsafe_links・do_stat()・FINFO・link_stat()・rprintf()・unsafe_symlink()・verbose.
参照元 make_file().
00173 { 00174 #ifdef SUPPORT_LINKS 00175 if (copy_links) 00176 return do_stat(path, buffer); 00177 if (link_stat(path, buffer, copy_dirlinks) < 0) 00178 return -1; 00179 if (S_ISLNK(buffer->st_mode)) { 00180 int l = readlink((char *)path, linkbuf, MAXPATHLEN - 1); 00181 if (l == -1) 00182 return -1; 00183 linkbuf[l] = 0; 00184 if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) { 00185 if (verbose > 1) { 00186 rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n", 00187 path, linkbuf); 00188 } 00189 return do_stat(path, buffer); 00190 } 00191 } 00192 return 0; 00193 #else 00194 return do_stat(path, buffer); 00195 #endif 00196 }
int link_stat | ( | const char * | path, | |
STRUCT_STAT * | buffer, | |||
int | follow_dirlinks | |||
) |
参照先 copy_links・do_lstat()・do_stat().
参照元 do_delete_pass()・hard_link_check()・hard_link_cluster()・readlink_stat()・recv_generator()・send_file_list()・set_file_attrs()・try_dests_non()・try_dests_reg().
00199 { 00200 #ifdef SUPPORT_LINKS 00201 if (copy_links) 00202 return do_stat(path, buffer); 00203 if (do_lstat(path, buffer) < 0) 00204 return -1; 00205 if (follow_dirlinks && S_ISLNK(buffer->st_mode)) { 00206 STRUCT_STAT st; 00207 if (do_stat(path, &st) == 0 && S_ISDIR(st.st_mode)) 00208 *buffer = st; 00209 } 00210 return 0; 00211 #else 00212 return do_stat(path, buffer); 00213 #endif 00214 }
static int is_excluded | ( | char * | fname, | |
int | is_dir, | |||
int | filter_level | |||
) | [static] |
参照先 check_filter()・filter_list・filter_list_struct::head・server_filter_list.
参照元 clean_flist()・make_file().
00220 { 00221 #if 0 /* This currently never happens, so avoid a useless compare. */ 00222 if (filter_level == NO_FILTERS) 00223 return 0; 00224 #endif 00225 if (fname) { 00226 /* never exclude '.', even if somebody does --exclude '*' */ 00227 if (fname[0] == '.' && !fname[1]) 00228 return 0; 00229 /* Handle the -R version of the '.' dir. */ 00230 if (fname[0] == '/') { 00231 int len = strlen(fname); 00232 if (fname[len-1] == '.' && fname[len-2] == '/') 00233 return 0; 00234 } 00235 } 00236 if (server_filter_list.head 00237 && check_filter(&server_filter_list, fname, is_dir) < 0) 00238 return 1; 00239 if (filter_level != ALL_FILTERS) 00240 return 0; 00241 if (filter_list.head 00242 && check_filter(&filter_list, fname, is_dir) < 0) 00243 return 1; 00244 return 0; 00245 }
static int to_wire_mode | ( | mode_t | mode | ) | [static] |
参照元 send_file_entry().
00248 { 00249 #ifdef SUPPORT_LINKS 00250 if (S_ISLNK(mode) && (_S_IFLNK != 0120000)) 00251 return (mode & ~(_S_IFMT)) | 0120000; 00252 #endif 00253 return (int)mode; 00254 }
static mode_t from_wire_mode | ( | int | mode | ) | [static] |
static void send_directory | ( | int | f, | |
struct file_list * | flist, | |||
char * | fbuf, | |||
int | len | |||
) | [static] |
参照先 file_list::count・d_name()・errno・FERROR・file_list::files・FINFO・full_fname()・io_error・recurse・rprintf()・rsyserr()・send_file_name()・send_if_directory()・strlcpy().
参照元 get_dirlist()・send_if_directory().
01042 { 01043 struct dirent *di; 01044 unsigned remainder; 01045 char *p; 01046 DIR *d; 01047 int start = flist->count; 01048 01049 if (!(d = opendir(fbuf))) { 01050 io_error |= IOERR_GENERAL; 01051 rsyserr(FERROR, errno, "opendir %s failed", full_fname(fbuf)); 01052 return; 01053 } 01054 01055 p = fbuf + len; 01056 if (len != 1 || *fbuf != '/') 01057 *p++ = '/'; 01058 *p = '\0'; 01059 remainder = MAXPATHLEN - (p - fbuf); 01060 01061 for (errno = 0, di = readdir(d); di; errno = 0, di = readdir(d)) { 01062 char *dname = d_name(di); 01063 if (dname[0] == '.' && (dname[1] == '\0' 01064 || (dname[1] == '.' && dname[2] == '\0'))) 01065 continue; 01066 if (strlcpy(p, dname, remainder) >= remainder) { 01067 io_error |= IOERR_GENERAL; 01068 rprintf(FINFO, 01069 "cannot send long-named file %s\n", 01070 full_fname(fbuf)); 01071 continue; 01072 } 01073 01074 send_file_name(f, flist, fbuf, NULL, 0); 01075 } 01076 01077 fbuf[len] = '\0'; 01078 01079 if (errno) { 01080 io_error |= IOERR_GENERAL; 01081 rsyserr(FERROR, errno, "readdir(%s)", full_fname(fbuf)); 01082 } 01083 01084 closedir(d); 01085 01086 if (recurse) { 01087 int i, end = flist->count - 1; 01088 for (i = start; i <= end; i++) 01089 send_if_directory(f, flist, flist->files[i], fbuf, len); 01090 } 01091 }
void flist_expand | ( | struct file_list * | flist | ) |
Make sure flist
is big enough to hold at least flist->count
entries.
参照先 file_list::count・file_list::files・FINFO・file_list::malloced・out_of_memory()・rprintf()・verbose・who_am_i().
参照元 recv_file_list()・send_file_name().
00275 { 00276 struct file_struct **new_ptr; 00277 00278 if (flist->count < flist->malloced) 00279 return; 00280 00281 if (flist->malloced < FLIST_START) 00282 flist->malloced = FLIST_START; 00283 else if (flist->malloced >= FLIST_LINEAR) 00284 flist->malloced += FLIST_LINEAR; 00285 else 00286 flist->malloced *= 2; 00287 00288 /* 00289 * In case count jumped or we are starting the list 00290 * with a known size just set it. 00291 */ 00292 if (flist->malloced < flist->count) 00293 flist->malloced = flist->count; 00294 00295 new_ptr = realloc_array(flist->files, struct file_struct *, 00296 flist->malloced); 00297 00298 if (verbose >= 2 && flist->malloced != FLIST_START) { 00299 rprintf(FINFO, "[%s] expand file_list to %.0f bytes, did%s move\n", 00300 who_am_i(), 00301 (double)sizeof flist->files[0] * flist->malloced, 00302 (new_ptr == flist->files) ? " not" : ""); 00303 } 00304 00305 flist->files = new_ptr; 00306 00307 if (!flist->files) 00308 out_of_memory("flist_expand"); 00309 }
static void send_file_entry | ( | struct file_struct * | file, | |
int | f | |||
) | [static] |
参照先 add_gid()・add_uid()・always_checksum・checksum_len・empty_sum・f_name()・file_struct::flags・file_struct::gid・file_struct::idev・file_struct::length・file_struct::link・file_struct::link_u・file_struct::mode・file_struct::modtime・numeric_ids・preserve_devices・preserve_gid・preserve_links・preserve_specials・preserve_uid・protocol_version・file_struct::rdev・strlcpy()・file_struct::sum・to_wire_mode()・file_struct::u・file_struct::uid・write_buf()・write_byte()・write_int()・write_longint().
参照元 send_file_list()・send_file_name().
00312 { 00313 unsigned short flags; 00314 static time_t modtime; 00315 static mode_t mode; 00316 static int64 dev; 00317 static dev_t rdev; 00318 static uint32 rdev_major; 00319 static uid_t uid; 00320 static gid_t gid; 00321 static char lastname[MAXPATHLEN]; 00322 char fname[MAXPATHLEN]; 00323 int l1, l2; 00324 00325 if (f < 0) 00326 return; 00327 00328 if (!file) { 00329 write_byte(f, 0); 00330 modtime = 0, mode = 0; 00331 dev = 0, rdev = makedev(0, 0); 00332 rdev_major = 0; 00333 uid = 0, gid = 0; 00334 *lastname = '\0'; 00335 return; 00336 } 00337 00338 f_name(file, fname); 00339 00340 flags = file->flags & XMIT_TOP_DIR; 00341 00342 if (file->mode == mode) 00343 flags |= XMIT_SAME_MODE; 00344 else 00345 mode = file->mode; 00346 if ((preserve_devices && IS_DEVICE(mode)) 00347 || (preserve_specials && IS_SPECIAL(mode))) { 00348 if (protocol_version < 28) { 00349 if (file->u.rdev == rdev) 00350 flags |= XMIT_SAME_RDEV_pre28; 00351 else 00352 rdev = file->u.rdev; 00353 } else { 00354 rdev = file->u.rdev; 00355 if ((uint32)major(rdev) == rdev_major) 00356 flags |= XMIT_SAME_RDEV_MAJOR; 00357 else 00358 rdev_major = major(rdev); 00359 if ((uint32)minor(rdev) <= 0xFFu) 00360 flags |= XMIT_RDEV_MINOR_IS_SMALL; 00361 } 00362 } else if (protocol_version < 28) 00363 rdev = makedev(0, 0); 00364 if (file->uid == uid) 00365 flags |= XMIT_SAME_UID; 00366 else 00367 uid = file->uid; 00368 if (file->gid == gid) 00369 flags |= XMIT_SAME_GID; 00370 else 00371 gid = file->gid; 00372 if (file->modtime == modtime) 00373 flags |= XMIT_SAME_TIME; 00374 else 00375 modtime = file->modtime; 00376 00377 #ifdef SUPPORT_HARD_LINKS 00378 if (file->link_u.idev) { 00379 if (file->F_DEV == dev) { 00380 if (protocol_version >= 28) 00381 flags |= XMIT_SAME_DEV; 00382 } else 00383 dev = file->F_DEV; 00384 flags |= XMIT_HAS_IDEV_DATA; 00385 } 00386 #endif 00387 00388 for (l1 = 0; 00389 lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255); 00390 l1++) {} 00391 l2 = strlen(fname+l1); 00392 00393 if (l1 > 0) 00394 flags |= XMIT_SAME_NAME; 00395 if (l2 > 255) 00396 flags |= XMIT_LONG_NAME; 00397 00398 /* We must make sure we don't send a zero flag byte or the 00399 * other end will terminate the flist transfer. Note that 00400 * the use of XMIT_TOP_DIR on a non-dir has no meaning, so 00401 * it's harmless way to add a bit to the first flag byte. */ 00402 if (protocol_version >= 28) { 00403 if (!flags && !S_ISDIR(mode)) 00404 flags |= XMIT_TOP_DIR; 00405 if ((flags & 0xFF00) || !flags) { 00406 flags |= XMIT_EXTENDED_FLAGS; 00407 write_byte(f, flags); 00408 write_byte(f, flags >> 8); 00409 } else 00410 write_byte(f, flags); 00411 } else { 00412 if (!(flags & 0xFF)) 00413 flags |= S_ISDIR(mode) ? XMIT_LONG_NAME : XMIT_TOP_DIR; 00414 write_byte(f, flags); 00415 } 00416 if (flags & XMIT_SAME_NAME) 00417 write_byte(f, l1); 00418 if (flags & XMIT_LONG_NAME) 00419 write_int(f, l2); 00420 else 00421 write_byte(f, l2); 00422 write_buf(f, fname + l1, l2); 00423 00424 write_longint(f, file->length); 00425 if (!(flags & XMIT_SAME_TIME)) 00426 write_int(f, modtime); 00427 if (!(flags & XMIT_SAME_MODE)) 00428 write_int(f, to_wire_mode(mode)); 00429 if (preserve_uid && !(flags & XMIT_SAME_UID)) { 00430 if (!numeric_ids) 00431 add_uid(uid); 00432 write_int(f, uid); 00433 } 00434 if (preserve_gid && !(flags & XMIT_SAME_GID)) { 00435 if (!numeric_ids) 00436 add_gid(gid); 00437 write_int(f, gid); 00438 } 00439 if ((preserve_devices && IS_DEVICE(mode)) 00440 || (preserve_specials && IS_SPECIAL(mode))) { 00441 if (protocol_version < 28) { 00442 if (!(flags & XMIT_SAME_RDEV_pre28)) 00443 write_int(f, (int)rdev); 00444 } else { 00445 if (!(flags & XMIT_SAME_RDEV_MAJOR)) 00446 write_int(f, major(rdev)); 00447 if (flags & XMIT_RDEV_MINOR_IS_SMALL) 00448 write_byte(f, minor(rdev)); 00449 else 00450 write_int(f, minor(rdev)); 00451 } 00452 } 00453 00454 #ifdef SUPPORT_LINKS 00455 if (preserve_links && S_ISLNK(mode)) { 00456 int len = strlen(file->u.link); 00457 write_int(f, len); 00458 write_buf(f, file->u.link, len); 00459 } 00460 #endif 00461 00462 #ifdef SUPPORT_HARD_LINKS 00463 if (flags & XMIT_HAS_IDEV_DATA) { 00464 if (protocol_version < 26) { 00465 /* 32-bit dev_t and ino_t */ 00466 write_int(f, dev); 00467 write_int(f, file->F_INODE); 00468 } else { 00469 /* 64-bit dev_t and ino_t */ 00470 if (!(flags & XMIT_SAME_DEV)) 00471 write_longint(f, dev); 00472 write_longint(f, file->F_INODE); 00473 } 00474 } 00475 #endif 00476 00477 if (always_checksum && (S_ISREG(mode) || protocol_version < 28)) { 00478 char *sum; 00479 if (S_ISREG(mode)) 00480 sum = file->u.sum; 00481 else { 00482 /* Prior to 28, we sent a useless set of nulls. */ 00483 sum = empty_sum; 00484 } 00485 write_buf(f, sum, checksum_len); 00486 } 00487 00488 strlcpy(lastname, fname, MAXPATHLEN); 00489 }
static struct file_struct* receive_file_entry | ( | struct file_list * | flist, | |
unsigned short | flags, | |||
int | f | |||
) | [static] |
参照先 always_checksum・file_struct::basename・checksum_len・chmod_modes・clean_fname()・count_dir_elements()・file_struct::depth・file_struct::dir・file_struct::dirname・empty_sum・FERROR・file_list::file_pool・file_struct_len・file_struct::flags・from_wire_mode()・file_struct::gid・file_list::hlink_pool・file_struct::idev・file_struct::length・file_struct::link・file_struct::link_u・file_struct::mode・file_struct::modtime・overflow_exit()・pool_alloc()・preserve_devices・preserve_gid・preserve_hard_links・preserve_links・preserve_specials・preserve_uid・protocol_version・file_struct::rdev・read_buf()・read_byte()・read_int()・read_longint()・read_sbuf()・recurse・relative_paths・rprintf()・sanitize_path()・sanitize_paths・strlcpy()・file_struct::sum・tweak_mode()・file_struct::u・file_struct::uid.
参照元 recv_file_list().
00493 { 00494 static time_t modtime; 00495 static mode_t mode; 00496 static int64 dev; 00497 static dev_t rdev; 00498 static uint32 rdev_major; 00499 static uid_t uid; 00500 static gid_t gid; 00501 static char lastname[MAXPATHLEN], *lastdir; 00502 static int lastdir_depth, lastdir_len = -1; 00503 static unsigned int del_hier_name_len = 0; 00504 static int in_del_hier = 0; 00505 char thisname[MAXPATHLEN]; 00506 unsigned int l1 = 0, l2 = 0; 00507 int alloc_len, basename_len, dirname_len, linkname_len, sum_len; 00508 OFF_T file_length; 00509 char *basename, *dirname, *bp; 00510 struct file_struct *file; 00511 00512 if (!flist) { 00513 modtime = 0, mode = 0; 00514 dev = 0, rdev = makedev(0, 0); 00515 rdev_major = 0; 00516 uid = 0, gid = 0; 00517 *lastname = '\0'; 00518 lastdir_len = -1; 00519 in_del_hier = 0; 00520 return NULL; 00521 } 00522 00523 if (flags & XMIT_SAME_NAME) 00524 l1 = read_byte(f); 00525 00526 if (flags & XMIT_LONG_NAME) 00527 l2 = read_int(f); 00528 else 00529 l2 = read_byte(f); 00530 00531 if (l2 >= MAXPATHLEN - l1) { 00532 rprintf(FERROR, 00533 "overflow: flags=0x%x l1=%d l2=%d lastname=%s\n", 00534 flags, l1, l2, lastname); 00535 overflow_exit("receive_file_entry"); 00536 } 00537 00538 strlcpy(thisname, lastname, l1 + 1); 00539 read_sbuf(f, &thisname[l1], l2); 00540 thisname[l1 + l2] = 0; 00541 00542 strlcpy(lastname, thisname, MAXPATHLEN); 00543 00544 clean_fname(thisname, 0); 00545 00546 if (sanitize_paths) 00547 sanitize_path(thisname, thisname, "", 0); 00548 00549 if ((basename = strrchr(thisname, '/')) != NULL) { 00550 dirname_len = ++basename - thisname; /* counts future '\0' */ 00551 if (lastdir_len == dirname_len - 1 00552 && strncmp(thisname, lastdir, lastdir_len) == 0) { 00553 dirname = lastdir; 00554 dirname_len = 0; /* indicates no copy is needed */ 00555 } else 00556 dirname = thisname; 00557 } else { 00558 basename = thisname; 00559 dirname = NULL; 00560 dirname_len = 0; 00561 } 00562 basename_len = strlen(basename) + 1; /* count the '\0' */ 00563 00564 file_length = read_longint(f); 00565 if (!(flags & XMIT_SAME_TIME)) 00566 modtime = (time_t)read_int(f); 00567 if (!(flags & XMIT_SAME_MODE)) 00568 mode = from_wire_mode(read_int(f)); 00569 00570 if (chmod_modes && !S_ISLNK(mode)) 00571 mode = tweak_mode(mode, chmod_modes); 00572 00573 if (preserve_uid && !(flags & XMIT_SAME_UID)) 00574 uid = (uid_t)read_int(f); 00575 if (preserve_gid && !(flags & XMIT_SAME_GID)) 00576 gid = (gid_t)read_int(f); 00577 00578 if ((preserve_devices && IS_DEVICE(mode)) 00579 || (preserve_specials && IS_SPECIAL(mode))) { 00580 if (protocol_version < 28) { 00581 if (!(flags & XMIT_SAME_RDEV_pre28)) 00582 rdev = (dev_t)read_int(f); 00583 } else { 00584 uint32 rdev_minor; 00585 if (!(flags & XMIT_SAME_RDEV_MAJOR)) 00586 rdev_major = read_int(f); 00587 if (flags & XMIT_RDEV_MINOR_IS_SMALL) 00588 rdev_minor = read_byte(f); 00589 else 00590 rdev_minor = read_int(f); 00591 rdev = makedev(rdev_major, rdev_minor); 00592 } 00593 } else if (protocol_version < 28) 00594 rdev = makedev(0, 0); 00595 00596 #ifdef SUPPORT_LINKS 00597 if (preserve_links && S_ISLNK(mode)) { 00598 linkname_len = read_int(f) + 1; /* count the '\0' */ 00599 if (linkname_len <= 0 || linkname_len > MAXPATHLEN) { 00600 rprintf(FERROR, "overflow: linkname_len=%d\n", 00601 linkname_len - 1); 00602 overflow_exit("receive_file_entry"); 00603 } 00604 } 00605 else 00606 #endif 00607 linkname_len = 0; 00608 00609 sum_len = always_checksum && S_ISREG(mode) ? MD4_SUM_LENGTH : 0; 00610 00611 alloc_len = file_struct_len + dirname_len + basename_len 00612 + linkname_len + sum_len; 00613 bp = pool_alloc(flist->file_pool, alloc_len, "receive_file_entry"); 00614 00615 file = (struct file_struct *)bp; 00616 memset(bp, 0, file_struct_len); 00617 bp += file_struct_len; 00618 00619 file->modtime = modtime; 00620 file->length = file_length; 00621 file->mode = mode; 00622 file->uid = uid; 00623 file->gid = gid; 00624 00625 if (dirname_len) { 00626 file->dirname = lastdir = bp; 00627 lastdir_len = dirname_len - 1; 00628 memcpy(bp, dirname, dirname_len - 1); 00629 bp += dirname_len; 00630 bp[-1] = '\0'; 00631 lastdir_depth = count_dir_elements(lastdir); 00632 file->dir.depth = lastdir_depth + 1; 00633 } else if (dirname) { 00634 file->dirname = dirname; /* we're reusing lastname */ 00635 file->dir.depth = lastdir_depth + 1; 00636 } else 00637 file->dir.depth = 1; 00638 00639 if (S_ISDIR(mode)) { 00640 if (basename_len == 1+1 && *basename == '.') /* +1 for '\0' */ 00641 file->dir.depth--; 00642 if (flags & XMIT_TOP_DIR) { 00643 in_del_hier = recurse; 00644 del_hier_name_len = file->dir.depth == 0 ? 0 : l1 + l2; 00645 if (relative_paths && del_hier_name_len > 2 00646 && lastname[del_hier_name_len-1] == '.' 00647 && lastname[del_hier_name_len-2] == '/') 00648 del_hier_name_len -= 2; 00649 file->flags |= FLAG_TOP_DIR | FLAG_DEL_HERE; 00650 } else if (in_del_hier) { 00651 if (!relative_paths || !del_hier_name_len 00652 || (l1 >= del_hier_name_len 00653 && lastname[del_hier_name_len] == '/')) 00654 file->flags |= FLAG_DEL_HERE; 00655 else 00656 in_del_hier = 0; 00657 } 00658 } 00659 00660 file->basename = bp; 00661 memcpy(bp, basename, basename_len); 00662 bp += basename_len; 00663 00664 if ((preserve_devices && IS_DEVICE(mode)) 00665 || (preserve_specials && IS_SPECIAL(mode))) 00666 file->u.rdev = rdev; 00667 00668 #ifdef SUPPORT_LINKS 00669 if (linkname_len) { 00670 file->u.link = bp; 00671 read_sbuf(f, bp, linkname_len - 1); 00672 if (sanitize_paths) 00673 sanitize_path(bp, bp, "", lastdir_depth); 00674 bp += linkname_len; 00675 } 00676 #endif 00677 00678 #ifdef SUPPORT_HARD_LINKS 00679 if (preserve_hard_links && protocol_version < 28 && S_ISREG(mode)) 00680 flags |= XMIT_HAS_IDEV_DATA; 00681 if (flags & XMIT_HAS_IDEV_DATA) { 00682 int64 inode; 00683 if (protocol_version < 26) { 00684 dev = read_int(f); 00685 inode = read_int(f); 00686 } else { 00687 if (!(flags & XMIT_SAME_DEV)) 00688 dev = read_longint(f); 00689 inode = read_longint(f); 00690 } 00691 if (flist->hlink_pool) { 00692 file->link_u.idev = pool_talloc(flist->hlink_pool, 00693 struct idev, 1, "inode_table"); 00694 file->F_INODE = inode; 00695 file->F_DEV = dev; 00696 } 00697 } 00698 #endif 00699 00700 if (always_checksum && (sum_len || protocol_version < 28)) { 00701 char *sum; 00702 if (sum_len) { 00703 file->u.sum = sum = bp; 00704 /*bp += sum_len;*/ 00705 } else { 00706 /* Prior to 28, we get a useless set of nulls. */ 00707 sum = empty_sum; 00708 } 00709 read_buf(f, sum, checksum_len); 00710 } 00711 00712 return file; 00713 }
struct file_struct* make_file | ( | char * | fname, | |
struct file_list * | flist, | |||
STRUCT_STAT * | stp, | |||
unsigned short | flags, | |||
int | filter_level | |||
) |
Create a file_struct for a named file by reading its stat() information and performing extensive checks against global options.
参照先 always_checksum・am_daemon・am_sender・file_struct::basename・clean_fname()・copy_links・file_list::count・file_struct::dir・file_struct::dirname・do_lstat()・do_stat()・errno・FERROR・file_checksum()・file_list::file_pool・file_struct_len・filesystem_dev・FINFO・file_struct::flags・flist_dir・flist_dir_len・flist_find()・full_fname()・file_struct::gid・file_list::hlink_pool・file_struct::idev・io_error・is_excluded()・keep_dirlinks・file_struct::length・file_struct::link・file_struct::link_u・file_struct::mode・file_struct::modtime・module_id・one_file_system・out_of_memory()・pool_alloc()・preserve_devices・preserve_specials・protocol_version・file_struct::rdev・readlink_stat()・file_struct::root・rprintf()・rsyserr()・sanitize_path()・sanitize_paths・stats・strlcpy()・file_struct::sum・the_file_list・stats::total_size・file_struct::u・file_struct::uid・verbose・who_am_i()・xfer_dirs.
参照元 keep_backup()・recv_generator()・send_file_name().
00733 { 00734 static char *lastdir; 00735 static int lastdir_len = -1; 00736 struct file_struct *file; 00737 STRUCT_STAT st; 00738 char sum[SUM_LENGTH]; 00739 char thisname[MAXPATHLEN]; 00740 char linkname[MAXPATHLEN]; 00741 int alloc_len, basename_len, dirname_len, linkname_len, sum_len; 00742 char *basename, *dirname, *bp; 00743 00744 if (!flist || !flist->count) /* Ignore lastdir when invalid. */ 00745 lastdir_len = -1; 00746 00747 if (strlcpy(thisname, fname, sizeof thisname) 00748 >= sizeof thisname - flist_dir_len) { 00749 rprintf(FINFO, "skipping overly long name: %s\n", fname); 00750 return NULL; 00751 } 00752 clean_fname(thisname, 0); 00753 if (sanitize_paths) 00754 sanitize_path(thisname, thisname, "", 0); 00755 00756 memset(sum, 0, SUM_LENGTH); 00757 00758 if (stp && S_ISDIR(stp->st_mode)) 00759 st = *stp; /* Needed for "symlink/." with --relative. */ 00760 else if (readlink_stat(thisname, &st, linkname) != 0) { 00761 int save_errno = errno; 00762 /* See if file is excluded before reporting an error. */ 00763 if (filter_level != NO_FILTERS 00764 && is_excluded(thisname, 0, filter_level)) 00765 return NULL; 00766 if (save_errno == ENOENT) { 00767 #ifdef SUPPORT_LINKS 00768 /* Avoid "vanished" error if symlink points nowhere. */ 00769 if (copy_links && do_lstat(thisname, &st) == 0 00770 && S_ISLNK(st.st_mode)) { 00771 io_error |= IOERR_GENERAL; 00772 rprintf(FERROR, "symlink has no referent: %s\n", 00773 full_fname(thisname)); 00774 } else 00775 #endif 00776 { 00777 enum logcode c = am_daemon && protocol_version < 28 00778 ? FERROR : FINFO; 00779 io_error |= IOERR_VANISHED; 00780 rprintf(c, "file has vanished: %s\n", 00781 full_fname(thisname)); 00782 } 00783 } else { 00784 io_error |= IOERR_GENERAL; 00785 rsyserr(FERROR, save_errno, "readlink %s failed", 00786 full_fname(thisname)); 00787 } 00788 return NULL; 00789 } 00790 00791 /* backup.c calls us with filter_level set to NO_FILTERS. */ 00792 if (filter_level == NO_FILTERS) 00793 goto skip_filters; 00794 00795 if (S_ISDIR(st.st_mode) && !xfer_dirs) { 00796 rprintf(FINFO, "skipping directory %s\n", thisname); 00797 return NULL; 00798 } 00799 00800 /* We only care about directories because we need to avoid recursing 00801 * into a mount-point directory, not to avoid copying a symlinked 00802 * file if -L (or similar) was specified. */ 00803 if (one_file_system && st.st_dev != filesystem_dev 00804 && S_ISDIR(st.st_mode)) { 00805 if (one_file_system > 1) { 00806 if (verbose > 2) { 00807 rprintf(FINFO, "skipping mount-point dir %s\n", 00808 thisname); 00809 } 00810 return NULL; 00811 } 00812 flags |= FLAG_MOUNT_POINT; 00813 } 00814 00815 if (is_excluded(thisname, S_ISDIR(st.st_mode) != 0, filter_level)) 00816 return NULL; 00817 00818 if (lp_ignore_nonreadable(module_id)) { 00819 #ifdef SUPPORT_LINKS 00820 if (!S_ISLNK(st.st_mode)) 00821 #endif 00822 if (access(thisname, R_OK) != 0) 00823 return NULL; 00824 } 00825 00826 skip_filters: 00827 00828 if (verbose > 2) { 00829 rprintf(FINFO, "[%s] make_file(%s,*,%d)\n", 00830 who_am_i(), thisname, filter_level); 00831 } 00832 00833 if ((basename = strrchr(thisname, '/')) != NULL) { 00834 dirname_len = ++basename - thisname; /* counts future '\0' */ 00835 if (lastdir_len == dirname_len - 1 00836 && strncmp(thisname, lastdir, lastdir_len) == 0) { 00837 dirname = lastdir; 00838 dirname_len = 0; /* indicates no copy is needed */ 00839 } else 00840 dirname = thisname; 00841 } else { 00842 basename = thisname; 00843 dirname = NULL; 00844 dirname_len = 0; 00845 } 00846 basename_len = strlen(basename) + 1; /* count the '\0' */ 00847 00848 #ifdef SUPPORT_LINKS 00849 linkname_len = S_ISLNK(st.st_mode) ? strlen(linkname) + 1 : 0; 00850 #else 00851 linkname_len = 0; 00852 #endif 00853 00854 sum_len = always_checksum && am_sender && S_ISREG(st.st_mode) 00855 ? MD4_SUM_LENGTH : 0; 00856 00857 alloc_len = file_struct_len + dirname_len + basename_len 00858 + linkname_len + sum_len; 00859 if (flist) 00860 bp = pool_alloc(flist->file_pool, alloc_len, "make_file"); 00861 else { 00862 if (!(bp = new_array(char, alloc_len))) 00863 out_of_memory("make_file"); 00864 } 00865 00866 file = (struct file_struct *)bp; 00867 memset(bp, 0, file_struct_len); 00868 bp += file_struct_len; 00869 00870 file->flags = flags; 00871 file->modtime = st.st_mtime; 00872 file->length = st.st_size; 00873 file->mode = st.st_mode; 00874 file->uid = st.st_uid; 00875 file->gid = st.st_gid; 00876 00877 #ifdef SUPPORT_HARD_LINKS 00878 if (flist && flist->hlink_pool) { 00879 if (protocol_version < 28) { 00880 if (S_ISREG(st.st_mode)) 00881 file->link_u.idev = pool_talloc( 00882 flist->hlink_pool, struct idev, 1, 00883 "inode_table"); 00884 } else { 00885 if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) 00886 file->link_u.idev = pool_talloc( 00887 flist->hlink_pool, struct idev, 1, 00888 "inode_table"); 00889 } 00890 } 00891 if (file->link_u.idev) { 00892 file->F_DEV = st.st_dev; 00893 file->F_INODE = st.st_ino; 00894 } 00895 #endif 00896 00897 if (dirname_len) { 00898 file->dirname = lastdir = bp; 00899 lastdir_len = dirname_len - 1; 00900 memcpy(bp, dirname, dirname_len - 1); 00901 bp += dirname_len; 00902 bp[-1] = '\0'; 00903 } else if (dirname) 00904 file->dirname = dirname; 00905 00906 file->basename = bp; 00907 memcpy(bp, basename, basename_len); 00908 bp += basename_len; 00909 00910 #ifdef HAVE_STRUCT_STAT_ST_RDEV 00911 if ((preserve_devices && IS_DEVICE(st.st_mode)) 00912 || (preserve_specials && IS_SPECIAL(st.st_mode))) 00913 file->u.rdev = st.st_rdev; 00914 #endif 00915 00916 #ifdef SUPPORT_LINKS 00917 if (linkname_len) { 00918 file->u.link = bp; 00919 memcpy(bp, linkname, linkname_len); 00920 bp += linkname_len; 00921 } 00922 #endif 00923 00924 if (sum_len) { 00925 file->u.sum = bp; 00926 file_checksum(thisname, bp, st.st_size); 00927 /*bp += sum_len;*/ 00928 } 00929 00930 file->dir.root = flist_dir; 00931 00932 /* This code is only used by the receiver when it is building 00933 * a list of files for a delete pass. */ 00934 if (keep_dirlinks && linkname_len && flist) { 00935 STRUCT_STAT st2; 00936 int save_mode = file->mode; 00937 file->mode = S_IFDIR; /* Find a directory with our name. */ 00938 if (flist_find(the_file_list, file) >= 0 00939 && do_stat(thisname, &st2) == 0 && S_ISDIR(st2.st_mode)) { 00940 file->modtime = st2.st_mtime; 00941 file->length = st2.st_size; 00942 file->mode = st2.st_mode; 00943 file->uid = st2.st_uid; 00944 file->gid = st2.st_gid; 00945 file->u.link = NULL; 00946 } else 00947 file->mode = save_mode; 00948 } 00949 00950 if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) 00951 stats.total_size += st.st_size; 00952 00953 return file; 00954 }
static struct file_struct* send_file_name | ( | int | f, | |
struct file_list * | flist, | |||
char * | fname, | |||
STRUCT_STAT * | stp, | |||
unsigned short | flags | |||
) | [static] |
参照先 file_struct::basename・chmod_modes・file_list::count・file_list::files・flist_count_offset・flist_expand()・make_acl()・make_file()・make_xattr()・maybe_emit_filelist_progress()・file_struct::mode・preserve_acls・preserve_xattrs・send_acl()・send_file_entry()・send_xattr()・tweak_mode().
参照元 send_directory()・send_file_list().
00959 { 00960 struct file_struct *file; 00961 00962 file = make_file(fname, flist, stp, flags, 00963 f == -2 ? SERVER_FILTERS : ALL_FILTERS); 00964 if (!file) 00965 return NULL; 00966 00967 if (chmod_modes && !S_ISLNK(file->mode)) 00968 file->mode = tweak_mode(file->mode, chmod_modes); 00969 00970 #ifdef SUPPORT_ACLS 00971 if (preserve_acls && make_acl(file, fname) < 0) 00972 return NULL; 00973 #endif 00974 #ifdef SUPPORT_XATTRS 00975 if (preserve_xattrs && make_xattr(file, fname) < 0) 00976 return NULL; 00977 #endif 00978 00979 maybe_emit_filelist_progress(flist->count + flist_count_offset); 00980 00981 flist_expand(flist); 00982 00983 if (file->basename[0]) { 00984 flist->files[flist->count++] = file; 00985 send_file_entry(file, f); 00986 #ifdef SUPPORT_ACLS 00987 if (preserve_acls) 00988 send_acl(file, f); 00989 #endif 00990 #ifdef SUPPORT_XATTRS 00991 if (preserve_xattrs) 00992 send_xattr(file, f); 00993 #endif 00994 } else { 00995 #ifdef SUPPORT_ACLS 00996 /* Cleanup unsent ACL(s). */ 00997 if (preserve_acls) 00998 send_acl(file, -1); 00999 #endif 01000 #ifdef SUPPORT_XATTRS 01001 if (preserve_xattrs) 01002 send_xattr(file, -1); 01003 #endif 01004 } 01005 return file; 01006 }
static void send_if_directory | ( | int | f, | |
struct file_list * | flist, | |||
struct file_struct * | file, | |||
char * | fbuf, | |||
unsigned int | ol | |||
) | [static] |
参照先 f_name()・FERROR・file_struct::flags・full_fname()・io_error・file_struct::mode・pop_local_filters()・push_local_filters()・rprintf()・send_directory().
参照元 send_directory()・send_file_list().
01011 { 01012 char is_dot_dir = fbuf[ol-1] == '.' && (ol == 1 || fbuf[ol-2] == '/'); 01013 01014 if (S_ISDIR(file->mode) 01015 && !(file->flags & FLAG_MOUNT_POINT) && f_name(file, fbuf)) { 01016 void *save_filters; 01017 unsigned int len = strlen(fbuf); 01018 if (len > 1 && fbuf[len-1] == '/') 01019 fbuf[--len] = '\0'; 01020 if (len >= MAXPATHLEN - 1) { 01021 io_error |= IOERR_GENERAL; 01022 rprintf(FERROR, "skipping long-named directory: %s\n", 01023 full_fname(fbuf)); 01024 return; 01025 } 01026 save_filters = push_local_filters(fbuf, len); 01027 send_directory(f, flist, fbuf, len); 01028 pop_local_filters(save_filters); 01029 fbuf[ol] = '\0'; 01030 if (is_dot_dir) 01031 fbuf[ol-1] = '.'; 01032 } 01033 }
struct file_list* send_file_list | ( | int | f, | |
int | argc, | |||
char * | argv[] | |||
) |
参照先 clean_flist()・copy_dirlinks・copy_links・copy_unsafe_links・file_list::count・curr_dir・errno・FERROR・filesfrom_fd・filesystem_dev・FINFO・finish_filelist_progress()・stats::flist_buildtime・flist_dir・flist_dir_len・flist_new()・stats::flist_size・stats::flist_xfertime・full_fname()・file_list::hlink_pool・implied_dirs・io_end_buffering()・io_error・io_start_buffering_out()・link_stat()・memmove()・module_id・stats::num_files・one_file_system・output_flist()・overflow_exit()・pool_destroy()・pop_dir()・push_dir()・read_filesfrom_line()・recurse・relative_paths・rprintf()・rsyserr()・sanitize_path()・sanitize_paths・send_file_entry()・send_file_name()・send_if_directory()・send_uid_list()・show_filelist_p()・start_filelist_progress()・stats・strdup()・strlcpy()・stats::total_written・verbose・write_int()・xfer_dirs.
参照元 client_run()・do_server_sender().
01094 { 01095 int len; 01096 STRUCT_STAT st; 01097 char *p, *dir, olddir[sizeof curr_dir]; 01098 char lastpath[MAXPATHLEN] = ""; 01099 struct file_list *flist; 01100 struct timeval start_tv, end_tv; 01101 int64 start_write; 01102 int use_ff_fd = 0; 01103 01104 if (show_filelist_p()) 01105 start_filelist_progress("building file list"); 01106 01107 start_write = stats.total_written; 01108 gettimeofday(&start_tv, NULL); 01109 01110 flist = flist_new(WITH_HLINK, "send_file_list"); 01111 01112 io_start_buffering_out(); 01113 if (filesfrom_fd >= 0) { 01114 if (argv[0] && !push_dir(argv[0])) { 01115 rsyserr(FERROR, errno, "push_dir %s failed", 01116 full_fname(argv[0])); 01117 exit_cleanup(RERR_FILESELECT); 01118 } 01119 use_ff_fd = 1; 01120 } 01121 01122 while (1) { 01123 char fbuf[MAXPATHLEN]; 01124 char *fn; 01125 int is_dot_dir; 01126 01127 if (use_ff_fd) { 01128 if (read_filesfrom_line(filesfrom_fd, fbuf) == 0) 01129 break; 01130 sanitize_path(fbuf, fbuf, "", 0); 01131 } else { 01132 if (argc-- == 0) 01133 break; 01134 strlcpy(fbuf, *argv++, MAXPATHLEN); 01135 if (sanitize_paths) 01136 sanitize_path(fbuf, fbuf, "", 0); 01137 } 01138 01139 len = strlen(fbuf); 01140 if (relative_paths) { 01141 /* We clean up fbuf below. */ 01142 is_dot_dir = 0; 01143 } else if (!len || fbuf[len - 1] == '/') { 01144 if (len == 2 && fbuf[0] == '.') { 01145 /* Turn "./" into just "." rather than "./." */ 01146 fbuf[1] = '\0'; 01147 } else { 01148 if (len + 1 >= MAXPATHLEN) 01149 overflow_exit("send_file_list"); 01150 fbuf[len++] = '.'; 01151 fbuf[len] = '\0'; 01152 } 01153 is_dot_dir = 1; 01154 } else if (len > 1 && fbuf[len-1] == '.' && fbuf[len-2] == '.' 01155 && (len == 2 || fbuf[len-3] == '/')) { 01156 if (len + 2 >= MAXPATHLEN) 01157 overflow_exit("send_file_list"); 01158 fbuf[len++] = '/'; 01159 fbuf[len++] = '.'; 01160 fbuf[len] = '\0'; 01161 is_dot_dir = 1; 01162 } else { 01163 is_dot_dir = fbuf[len-1] == '.' 01164 && (len == 1 || fbuf[len-2] == '/'); 01165 } 01166 01167 if (link_stat(fbuf, &st, copy_dirlinks) != 0) { 01168 io_error |= IOERR_GENERAL; 01169 rsyserr(FERROR, errno, "link_stat %s failed", 01170 full_fname(fbuf)); 01171 continue; 01172 } 01173 01174 if (S_ISDIR(st.st_mode) && !xfer_dirs) { 01175 rprintf(FINFO, "skipping directory %s\n", fbuf); 01176 continue; 01177 } 01178 01179 dir = NULL; 01180 olddir[0] = '\0'; 01181 01182 if (!relative_paths) { 01183 p = strrchr(fbuf, '/'); 01184 if (p) { 01185 *p = '\0'; 01186 if (p == fbuf) 01187 dir = "/"; 01188 else 01189 dir = fbuf; 01190 len -= p - fbuf + 1; 01191 fn = p + 1; 01192 } else 01193 fn = fbuf; 01194 } else { 01195 if ((p = strstr(fbuf, "/./")) != NULL) { 01196 *p = '\0'; 01197 if (p == fbuf) 01198 dir = "/"; 01199 else 01200 dir = fbuf; 01201 len -= p - fbuf + 3; 01202 fn = p + 3; 01203 } else 01204 fn = fbuf; 01205 /* Get rid of trailing "/" and "/.". */ 01206 while (len) { 01207 if (fn[len - 1] == '/') { 01208 is_dot_dir = 1; 01209 if (!--len && !dir) { 01210 len++; 01211 break; 01212 } 01213 } 01214 else if (len >= 2 && fn[len - 1] == '.' 01215 && fn[len - 2] == '/') { 01216 is_dot_dir = 1; 01217 if (!(len -= 2) && !dir) { 01218 len++; 01219 break; 01220 } 01221 } else 01222 break; 01223 } 01224 fn[len] = '\0'; 01225 /* Reject a ".." dir in the active part of the path. */ 01226 for (p = fn; (p = strstr(p, "..")) != NULL; p += 2) { 01227 if ((p[2] == '/' || p[2] == '\0') 01228 && (p == fn || p[-1] == '/')) { 01229 rprintf(FERROR, 01230 "found \"..\" dir in relative path: %s\n", 01231 fbuf); 01232 exit_cleanup(RERR_SYNTAX); 01233 } 01234 } 01235 } 01236 01237 if (!*fn) { 01238 len = 1; 01239 fn = "."; 01240 } 01241 01242 if (dir && *dir) { 01243 static char *lastdir; 01244 static int lastdir_len; 01245 01246 strlcpy(olddir, curr_dir, sizeof olddir); 01247 01248 if (!push_dir(dir)) { 01249 io_error |= IOERR_GENERAL; 01250 rsyserr(FERROR, errno, "push_dir %s failed", 01251 full_fname(dir)); 01252 continue; 01253 } 01254 01255 if (lastdir && strcmp(lastdir, dir) == 0) { 01256 flist_dir = lastdir; 01257 flist_dir_len = lastdir_len; 01258 } else { 01259 flist_dir = lastdir = strdup(dir); 01260 flist_dir_len = lastdir_len = strlen(dir); 01261 } 01262 } 01263 01264 if (fn != fbuf) 01265 memmove(fbuf, fn, len + 1); 01266 01267 if (implied_dirs && (p=strrchr(fbuf,'/')) && p != fbuf) { 01268 /* Send the implied directories at the start of the 01269 * source spec, so we get their permissions right. */ 01270 char *lp = lastpath, *slash = fbuf; 01271 *p = '\0'; 01272 /* Skip any initial directories in our path that we 01273 * have in common with lastpath. */ 01274 for (fn = fbuf; *fn && *lp == *fn; lp++, fn++) { 01275 if (*fn == '/') 01276 slash = fn; 01277 } 01278 *p = '/'; 01279 if (fn != p || (*lp && *lp != '/')) { 01280 int save_copy_links = copy_links; 01281 int save_xfer_dirs = xfer_dirs; 01282 copy_links |= copy_unsafe_links; 01283 xfer_dirs = 1; 01284 while ((slash = strchr(slash+1, '/')) != 0) { 01285 *slash = '\0'; 01286 send_file_name(f, flist, fbuf, NULL, 0); 01287 *slash = '/'; 01288 } 01289 copy_links = save_copy_links; 01290 xfer_dirs = save_xfer_dirs; 01291 *p = '\0'; 01292 strlcpy(lastpath, fbuf, sizeof lastpath); 01293 *p = '/'; 01294 } 01295 } 01296 01297 if (one_file_system) 01298 filesystem_dev = st.st_dev; 01299 01300 if (recurse || (xfer_dirs && is_dot_dir)) { 01301 struct file_struct *file; 01302 file = send_file_name(f, flist, fbuf, &st, FLAG_TOP_DIR); 01303 if (file) 01304 send_if_directory(f, flist, file, fbuf, len); 01305 } else 01306 send_file_name(f, flist, fbuf, &st, 0); 01307 01308 if (olddir[0]) { 01309 flist_dir = NULL; 01310 flist_dir_len = 0; 01311 if (!pop_dir(olddir)) { 01312 rsyserr(FERROR, errno, "pop_dir %s failed", 01313 full_fname(olddir)); 01314 exit_cleanup(RERR_FILESELECT); 01315 } 01316 } 01317 } 01318 01319 gettimeofday(&end_tv, NULL); 01320 stats.flist_buildtime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000 01321 + (end_tv.tv_usec - start_tv.tv_usec) / 1000; 01322 if (stats.flist_buildtime == 0) 01323 stats.flist_buildtime = 1; 01324 start_tv = end_tv; 01325 01326 send_file_entry(NULL, f); 01327 01328 if (show_filelist_p()) 01329 finish_filelist_progress(flist); 01330 01331 gettimeofday(&end_tv, NULL); 01332 stats.flist_xfertime = (int64)(end_tv.tv_sec - start_tv.tv_sec) * 1000 01333 + (end_tv.tv_usec - start_tv.tv_usec) / 1000; 01334 01335 if (flist->hlink_pool) { 01336 pool_destroy(flist->hlink_pool); 01337 flist->hlink_pool = NULL; 01338 } 01339 01340 /* Sort the list without removing any duplicates. This allows the 01341 * receiving side to ask for any name they like, which gives us the 01342 * flexibility to change the way we unduplicate names in the future 01343 * without causing a compatibility problem with older versions. */ 01344 clean_flist(flist, 0, 0); 01345 01346 send_uid_list(f); 01347 01348 /* send the io_error flag */ 01349 write_int(f, lp_ignore_errors(module_id) ? 0 : io_error); 01350 01351 io_end_buffering(); 01352 stats.flist_size = stats.total_written - start_write; 01353 stats.num_files = flist->count; 01354 01355 if (verbose > 3) 01356 output_flist(flist); 01357 01358 if (verbose > 2) 01359 rprintf(FINFO, "send_file_list done\n"); 01360 01361 return flist; 01362 }
struct file_list* recv_file_list | ( | int | f | ) |
参照先 clean_flist()・file_list::count・f_name()・file_list::files・FINFO・finish_filelist_progress()・flist_expand()・flist_new()・stats::flist_size・ignore_errors・io_error・list_file_entry()・list_only・file_list::malloced・maybe_emit_filelist_progress()・module_id・stats::num_files・out_of_memory()・output_flist()・preserve_acls・preserve_xattrs・protocol_version・read_byte()・read_int()・receive_acl()・receive_file_entry()・receive_xattr()・recv_uid_list()・relative_paths・rprintf()・show_filelist_p()・sort_file_acl_index_lists()・sort_file_xattr_index_lists()・start_filelist_progress()・stats・stats::total_read・stats::total_size・verbose.
参照元 client_run()・do_server_recv().
01365 { 01366 struct file_list *flist; 01367 unsigned short flags; 01368 int64 start_read; 01369 01370 if (show_filelist_p()) 01371 start_filelist_progress("receiving file list"); 01372 01373 start_read = stats.total_read; 01374 01375 flist = flist_new(WITH_HLINK, "recv_file_list"); 01376 01377 flist->count = 0; 01378 flist->malloced = 1000; 01379 flist->files = new_array(struct file_struct *, flist->malloced); 01380 if (!flist->files) 01381 goto oom; 01382 01383 while ((flags = read_byte(f)) != 0) { 01384 struct file_struct *file; 01385 01386 flist_expand(flist); 01387 01388 if (protocol_version >= 28 && (flags & XMIT_EXTENDED_FLAGS)) 01389 flags |= read_byte(f) << 8; 01390 file = receive_file_entry(flist, flags, f); 01391 01392 #ifdef SUPPORT_ACLS 01393 if (preserve_acls) 01394 receive_acl(file, f); 01395 #endif 01396 #ifdef SUPPORT_XATTRS 01397 if (preserve_xattrs) 01398 receive_xattr(file, f ); 01399 #endif 01400 01401 if (S_ISREG(file->mode) || S_ISLNK(file->mode)) 01402 stats.total_size += file->length; 01403 01404 flist->files[flist->count++] = file; 01405 01406 maybe_emit_filelist_progress(flist->count); 01407 01408 if (verbose > 2) { 01409 rprintf(FINFO, "recv_file_name(%s)\n", 01410 f_name(file, NULL)); 01411 } 01412 } 01413 receive_file_entry(NULL, 0, 0); /* Signal that we're done. */ 01414 01415 if (verbose > 2) 01416 rprintf(FINFO, "received %d names\n", flist->count); 01417 01418 if (show_filelist_p()) 01419 finish_filelist_progress(flist); 01420 01421 clean_flist(flist, relative_paths, 1); 01422 01423 #ifdef SUPPORT_ACLS 01424 if (preserve_acls) 01425 sort_file_acl_index_lists(); 01426 #endif 01427 #ifdef SUPPORT_XATTRS 01428 if (preserve_xattrs) 01429 sort_file_xattr_index_lists(); 01430 #endif 01431 01432 if (f >= 0) { 01433 recv_uid_list(f, flist); 01434 01435 /* Recv the io_error flag */ 01436 if (lp_ignore_errors(module_id) || ignore_errors) 01437 read_int(f); 01438 else 01439 io_error |= read_int(f); 01440 } 01441 01442 if (verbose > 3) 01443 output_flist(flist); 01444 01445 if (list_only) { 01446 int i; 01447 for (i = 0; i < flist->count; i++) 01448 list_file_entry(flist->files[i]); 01449 } 01450 01451 if (verbose > 2) 01452 rprintf(FINFO, "recv_file_list done\n"); 01453 01454 stats.flist_size = stats.total_read - start_read; 01455 stats.num_files = flist->count; 01456 01457 return flist; 01458 01459 oom: 01460 out_of_memory("recv_file_list"); 01461 return NULL; /* not reached */ 01462 }
static int file_compare | ( | struct file_struct ** | file1, | |
struct file_struct ** | file2 | |||
) | [static] |
int flist_find | ( | struct file_list * | flist, | |
struct file_struct * | f | |||
) |
参照先 file_struct::basename・file_struct::depth・file_struct::dir・f_name_cmp()・file_list::files・file_list::high・file_struct::length・file_list::low・file_struct::mode・protocol_version.
参照元 clean_flist()・delete_in_dir()・make_file()・recv_generator().
01472 { 01473 int low = flist->low, high = flist->high; 01474 int diff, mid, mid_up; 01475 01476 while (low <= high) { 01477 mid = (low + high) / 2; 01478 if (flist->files[mid]->basename) 01479 mid_up = mid; 01480 else { 01481 /* Scan for the next non-empty entry using the cached 01482 * distance values. If the value isn't fully up-to- 01483 * date, update it. */ 01484 mid_up = mid + flist->files[mid]->dir.depth; 01485 if (!flist->files[mid_up]->basename) { 01486 do { 01487 mid_up += flist->files[mid_up]->dir.depth; 01488 } while (!flist->files[mid_up]->basename); 01489 flist->files[mid]->dir.depth = mid_up - mid; 01490 } 01491 if (mid_up > high) { 01492 /* If there's nothing left above us, set high to 01493 * a non-empty entry below us and continue. */ 01494 high = mid - flist->files[mid]->length; 01495 if (!flist->files[high]->basename) { 01496 do { 01497 high -= flist->files[high]->length; 01498 } while (!flist->files[high]->basename); 01499 flist->files[mid]->length = mid - high; 01500 } 01501 continue; 01502 } 01503 } 01504 diff = f_name_cmp(flist->files[mid_up], f); 01505 if (diff == 0) { 01506 if (protocol_version < 29 01507 && S_ISDIR(flist->files[mid_up]->mode) 01508 != S_ISDIR(f->mode)) 01509 return -1; 01510 return mid_up; 01511 } 01512 if (diff < 0) 01513 low = mid_up + 1; 01514 else 01515 high = mid - 1; 01516 } 01517 return -1; 01518 }
void clear_file | ( | struct file_struct * | file, | |
struct file_list * | flist | |||
) |
参照先 file_struct::depth・file_struct::dir・file_struct_len・file_list::hlink_pool・file_struct::idev・file_struct::length・file_struct::link_u・pool_free().
参照元 clean_flist().
01525 { 01526 if (flist->hlink_pool && file->link_u.idev) 01527 pool_free(flist->hlink_pool, 0, file->link_u.idev); 01528 memset(file, 0, file_struct_len); 01529 /* In an empty entry, dir.depth is an offset to the next non-empty 01530 * entry. Likewise for length in the opposite direction. We assume 01531 * that we're alone for now since flist_find() will adjust the counts 01532 * it runs into that aren't up-to-date. */ 01533 file->length = file->dir.depth = 1; 01534 }
struct file_list* flist_new | ( | int | with_hlink, | |
char * | msg | |||
) |
参照先 file_list::file_pool・file_list::hlink_pool・out_of_memory()・pool_create()・preserve_hard_links.
参照元 get_dirlist()・recv_file_list()・send_file_list().
01540 { 01541 struct file_list *flist; 01542 01543 flist = new(struct file_list); 01544 if (!flist) 01545 out_of_memory(msg); 01546 01547 memset(flist, 0, sizeof (struct file_list)); 01548 01549 if (!(flist->file_pool = pool_create(FILE_EXTENT, 0, 01550 out_of_memory, POOL_INTERN))) 01551 out_of_memory(msg); 01552 01553 #ifdef SUPPORT_HARD_LINKS 01554 if (with_hlink && preserve_hard_links) { 01555 if (!(flist->hlink_pool = pool_create(HLINK_EXTENT, 01556 sizeof (struct idev), out_of_memory, POOL_INTERN))) 01557 out_of_memory(msg); 01558 } 01559 #endif 01560 01561 return flist; 01562 }
void flist_free | ( | struct file_list * | flist | ) |
参照先 file_list::file_pool・file_list::files・file_list::hlink_pool・pool_destroy().
参照元 delete_in_dir()・delete_item()・recv_generator().
01568 { 01569 pool_destroy(flist->file_pool); 01570 pool_destroy(flist->hlink_pool); 01571 free(flist->files); 01572 free(flist); 01573 }
int f_name_cmp | ( | struct file_struct * | f1, | |
struct file_struct * | f2 | |||
) |
参照先 file_struct::basename・file_struct::dirname・file_struct::mode・protocol_version・s_BASE・s_DIR・s_SLASH・t_PATH.
参照元 clean_flist()・file_compare()・flist_find()・hlink_compare().
01787 { 01788 int dif; 01789 const uchar *c1, *c2; 01790 enum fnc_state state1, state2; 01791 enum fnc_type type1, type2; 01792 enum fnc_type t_path = protocol_version >= 29 ? t_PATH : t_ITEM; 01793 01794 if (!f1 || !f1->basename) { 01795 if (!f2 || !f2->basename) 01796 return 0; 01797 return -1; 01798 } 01799 if (!f2 || !f2->basename) 01800 return 1; 01801 01802 c1 = (uchar*)f1->dirname; 01803 c2 = (uchar*)f2->dirname; 01804 if (c1 == c2) 01805 c1 = c2 = NULL; 01806 if (!c1) { 01807 type1 = S_ISDIR(f1->mode) ? t_path : t_ITEM; 01808 c1 = (uchar*)f1->basename; 01809 if (type1 == t_PATH && *c1 == '.' && !c1[1]) { 01810 type1 = t_ITEM; 01811 state1 = s_TRAILING; 01812 c1 = (uchar*)""; 01813 } else 01814 state1 = s_BASE; 01815 } else if (!*c1) { 01816 type1 = t_path; 01817 state1 = s_SLASH; 01818 c1 = (uchar*)"/"; 01819 } else { 01820 type1 = t_path; 01821 state1 = s_DIR; 01822 } 01823 if (!c2) { 01824 type2 = S_ISDIR(f2->mode) ? t_path : t_ITEM; 01825 c2 = (uchar*)f2->basename; 01826 if (type2 == t_PATH && *c2 == '.' && !c2[1]) { 01827 type2 = t_ITEM; 01828 state2 = s_TRAILING; 01829 c2 = (uchar*)""; 01830 } else 01831 state2 = s_BASE; 01832 } else if (!*c2) { 01833 type2 = t_path; 01834 state2 = s_SLASH; 01835 c2 = (uchar*)"/"; 01836 } else { 01837 type2 = t_path; 01838 state2 = s_DIR; 01839 } 01840 01841 if (type1 != type2) 01842 return type1 == t_PATH ? 1 : -1; 01843 01844 while (1) { 01845 if ((dif = (int)*c1++ - (int)*c2++) != 0) 01846 break; 01847 if (!*c1) { 01848 switch (state1) { 01849 case s_DIR: 01850 state1 = s_SLASH; 01851 c1 = (uchar*)"/"; 01852 break; 01853 case s_SLASH: 01854 type1 = S_ISDIR(f1->mode) ? t_path : t_ITEM; 01855 c1 = (uchar*)f1->basename; 01856 if (type1 == t_PATH && *c1 == '.' && !c1[1]) { 01857 type1 = t_ITEM; 01858 state1 = s_TRAILING; 01859 c1 = (uchar*)""; 01860 } else 01861 state1 = s_BASE; 01862 break; 01863 case s_BASE: 01864 state1 = s_TRAILING; 01865 if (type1 == t_PATH) { 01866 c1 = (uchar*)"/"; 01867 break; 01868 } 01869 /* FALL THROUGH */ 01870 case s_TRAILING: 01871 type1 = t_ITEM; 01872 break; 01873 } 01874 if (*c2 && type1 != type2) 01875 return type1 == t_PATH ? 1 : -1; 01876 } 01877 if (!*c2) { 01878 switch (state2) { 01879 case s_DIR: 01880 state2 = s_SLASH; 01881 c2 = (uchar*)"/"; 01882 break; 01883 case s_SLASH: 01884 type2 = S_ISDIR(f2->mode) ? t_path : t_ITEM; 01885 c2 = (uchar*)f2->basename; 01886 if (type2 == t_PATH && *c2 == '.' && !c2[1]) { 01887 type2 = t_ITEM; 01888 state2 = s_TRAILING; 01889 c2 = (uchar*)""; 01890 } else 01891 state2 = s_BASE; 01892 break; 01893 case s_BASE: 01894 state2 = s_TRAILING; 01895 if (type2 == t_PATH) { 01896 c2 = (uchar*)"/"; 01897 break; 01898 } 01899 /* FALL THROUGH */ 01900 case s_TRAILING: 01901 if (!*c1) 01902 return 0; 01903 type2 = t_ITEM; 01904 break; 01905 } 01906 if (type1 != type2) 01907 return type1 == t_PATH ? 1 : -1; 01908 } 01909 } 01910 01911 return dif; 01912 }
char* f_name | ( | struct file_struct * | f, | |
char * | fbuf | |||
) |
参照先 file_struct::basename・file_struct::dirname.
参照元 clean_flist()・delete_in_dir()・do_delete_pass()・generate_files()・get_next_gen_i()・handle_delayed_updates()・hard_link_check()・hard_link_cluster()・list_file_entry()・log_formatted()・receive_acl()・receive_xattr()・recv_file_list()・recv_files()・recv_generator()・send_file_entry()・send_files()・send_if_directory()・successful_send().
01919 { 01920 if (!f || !f->basename) 01921 return NULL; 01922 01923 if (!fbuf) { 01924 static char names[5][MAXPATHLEN]; 01925 static unsigned int n; 01926 01927 n = (n + 1) % (sizeof names / sizeof names[0]); 01928 01929 fbuf = names[n]; 01930 } 01931 01932 if (f->dirname) { 01933 int len = strlen(f->dirname); 01934 memcpy(fbuf, f->dirname, len); 01935 fbuf[len] = '/'; 01936 strcpy(fbuf + len + 1, f->basename); 01937 } else 01938 strcpy(fbuf, f->basename); 01939 01940 return fbuf; 01941 }
struct file_list* get_dirlist | ( | char * | dirname, | |
int | dlen, | |||
int | ignore_filter_rules | |||
) |
参照先 clean_flist()・file_list::count・dirbuf・do_progress・flist_count_offset・flist_new()・output_flist()・recurse・send_directory()・strlcpy()・verbose・xfer_dirs.
参照元 delete_in_dir()・delete_item()・recv_generator().
01950 { 01951 struct file_list *dirlist; 01952 char dirbuf[MAXPATHLEN]; 01953 int save_recurse = recurse; 01954 int save_xfer_dirs = xfer_dirs; 01955 01956 if (dlen < 0) { 01957 dlen = strlcpy(dirbuf, dirname, MAXPATHLEN); 01958 if (dlen >= MAXPATHLEN) 01959 return NULL; 01960 dirname = dirbuf; 01961 } 01962 01963 dirlist = flist_new(WITHOUT_HLINK, "get_dirlist"); 01964 01965 recurse = 0; 01966 xfer_dirs = 1; 01967 send_directory(ignore_filter_rules ? -2 : -1, dirlist, dirname, dlen); 01968 xfer_dirs = save_xfer_dirs; 01969 recurse = save_recurse; 01970 if (do_progress) 01971 flist_count_offset += dirlist->count; 01972 01973 clean_flist(dirlist, 0, 0); 01974 01975 if (verbose > 3) 01976 output_flist(dirlist); 01977 01978 return dirlist; 01979 }
int do_progress |
int always_checksum |
int module_id |
clientserver.c の 60 行で定義されています。
int ignore_errors |
int numeric_ids |
int filesfrom_fd |
int one_file_system |
int copy_dirlinks |
int keep_dirlinks |
int preserve_acls |
int preserve_xattrs |
int preserve_links |
int preserve_devices |
int preserve_uid |
int preserve_gid |
int relative_paths |
int prune_empty_dirs |
int copy_links |
int protocol_version |
int sanitize_paths |
参照元 handle_stats()・io_multiplex_write()・itemize()・log_delete()・log_exit()・log_formatted()・main()・make_file()・match_report()・matched()・maybe_log_item()・msg2sndr_flush()・output_summary()・readfd()・receive_data()・recv_file_list()・recv_files()・rprint_progress()・send_file_list()・send_files()・whine_about_eof()・writefd().
struct file_list* the_file_list |
struct chmod_mode_struct* chmod_modes |
struct filter_list_struct filter_list |
int checksum_len |
dev_t filesystem_dev |
unsigned int file_struct_len |
char empty_sum[MD4_SUM_LENGTH] [static] |
int flist_count_offset [static] |
char* flist_dir [static] |
int flist_dir_len [static] |