00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rsync.h"
00029
00030 extern int verbose;
00031 extern int list_only;
00032 extern int am_root;
00033 extern int am_server;
00034 extern int am_daemon;
00035 extern int am_sender;
00036 extern int do_progress;
00037 extern int always_checksum;
00038 extern int module_id;
00039 extern int ignore_errors;
00040 extern int numeric_ids;
00041 extern int recurse;
00042 extern int xfer_dirs;
00043 extern int filesfrom_fd;
00044 extern int one_file_system;
00045 extern int copy_dirlinks;
00046 extern int keep_dirlinks;
00047 extern int preserve_acls;
00048 extern int preserve_xattrs;
00049 extern int preserve_links;
00050 extern int preserve_hard_links;
00051 extern int preserve_devices;
00052 extern int preserve_specials;
00053 extern int preserve_uid;
00054 extern int preserve_gid;
00055 extern int relative_paths;
00056 extern int implied_dirs;
00057 extern int prune_empty_dirs;
00058 extern int copy_links;
00059 extern int copy_unsafe_links;
00060 extern int protocol_version;
00061 extern int sanitize_paths;
00062 extern struct stats stats;
00063 extern struct file_list *the_file_list;
00064
00065 extern char curr_dir[MAXPATHLEN];
00066
00067 extern struct chmod_mode_struct *chmod_modes;
00068
00069 extern struct filter_list_struct filter_list;
00070 extern struct filter_list_struct server_filter_list;
00071
00072 int io_error;
00073 int checksum_len;
00074 dev_t filesystem_dev;
00075 unsigned int file_struct_len;
00076
00077 static char empty_sum[MD4_SUM_LENGTH];
00078 static int flist_count_offset;
00079
00080 static void clean_flist(struct file_list *flist, int strip_root, int no_dups);
00081 static void output_flist(struct file_list *flist);
00082
00083 void init_flist(void)
00084 {
00085 struct file_struct f;
00086
00087
00088 file_struct_len = offsetof(struct file_struct, flags) + sizeof f.flags;
00089 checksum_len = protocol_version < 21 ? 2 : MD4_SUM_LENGTH;
00090 }
00091
00092 static int show_filelist_p(void)
00093 {
00094 return verbose && xfer_dirs && !am_server;
00095 }
00096
00097 static void start_filelist_progress(char *kind)
00098 {
00099 rprintf(FINFO, "%s ... ", kind);
00100 if (verbose > 1 || do_progress)
00101 rprintf(FINFO, "\n");
00102 rflush(FINFO);
00103 }
00104
00105 static void emit_filelist_progress(int count)
00106 {
00107 rprintf(FINFO, " %d files...\r", count);
00108 }
00109
00110 static void maybe_emit_filelist_progress(int count)
00111 {
00112 if (do_progress && show_filelist_p() && (count % 100) == 0)
00113 emit_filelist_progress(count);
00114 }
00115
00116 static void finish_filelist_progress(const struct file_list *flist)
00117 {
00118 if (do_progress) {
00119
00120 rprintf(FINFO, "%d file%sto consider\n",
00121 flist->count, flist->count == 1 ? " " : "s ");
00122 } else
00123 rprintf(FINFO, "done\n");
00124 }
00125
00126 void show_flist_stats(void)
00127 {
00128
00129 }
00130
00131 static void list_file_entry(struct file_struct *f)
00132 {
00133 char permbuf[PERMSTRING_SIZE];
00134
00135 if (!f->basename) {
00136
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 }
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 static int readlink_stat(const char *path, STRUCT_STAT *buffer, char *linkbuf)
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 }
00197
00198 int link_stat(const char *path, STRUCT_STAT *buffer, int follow_dirlinks)
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 }
00215
00216
00217
00218
00219 static int is_excluded(char *fname, int is_dir, int filter_level)
00220 {
00221 #if 0
00222 if (filter_level == NO_FILTERS)
00223 return 0;
00224 #endif
00225 if (fname) {
00226
00227 if (fname[0] == '.' && !fname[1])
00228 return 0;
00229
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 }
00246
00247 static int to_wire_mode(mode_t mode)
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 }
00255
00256 static mode_t from_wire_mode(int mode)
00257 {
00258 if ((mode & (_S_IFMT)) == 0120000 && (_S_IFLNK != 0120000))
00259 return (mode & ~(_S_IFMT)) | _S_IFLNK;
00260 return (mode_t)mode;
00261 }
00262
00263 static void send_directory(int f, struct file_list *flist,
00264 char *fbuf, int len);
00265
00266 static char *flist_dir;
00267 static int flist_dir_len;
00268
00269
00270
00271
00272
00273
00274 void flist_expand(struct file_list *flist)
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
00290
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 }
00310
00311 static void send_file_entry(struct file_struct *file, int f)
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
00399
00400
00401
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
00466 write_int(f, dev);
00467 write_int(f, file->F_INODE);
00468 } else {
00469
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
00483 sum = empty_sum;
00484 }
00485 write_buf(f, sum, checksum_len);
00486 }
00487
00488 strlcpy(lastname, fname, MAXPATHLEN);
00489 }
00490
00491 static struct file_struct *receive_file_entry(struct file_list *flist,
00492 unsigned short flags, int f)
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;
00551 if (lastdir_len == dirname_len - 1
00552 && strncmp(thisname, lastdir, lastdir_len) == 0) {
00553 dirname = lastdir;
00554 dirname_len = 0;
00555 } else
00556 dirname = thisname;
00557 } else {
00558 basename = thisname;
00559 dirname = NULL;
00560 dirname_len = 0;
00561 }
00562 basename_len = strlen(basename) + 1;
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;
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;
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 == '.')
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
00705 } else {
00706
00707 sum = empty_sum;
00708 }
00709 read_buf(f, sum, checksum_len);
00710 }
00711
00712 return file;
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 struct file_struct *make_file(char *fname, struct file_list *flist,
00731 STRUCT_STAT *stp, unsigned short flags,
00732 int filter_level)
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)
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;
00760 else if (readlink_stat(thisname, &st, linkname) != 0) {
00761 int save_errno = errno;
00762
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
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
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
00801
00802
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;
00835 if (lastdir_len == dirname_len - 1
00836 && strncmp(thisname, lastdir, lastdir_len) == 0) {
00837 dirname = lastdir;
00838 dirname_len = 0;
00839 } else
00840 dirname = thisname;
00841 } else {
00842 basename = thisname;
00843 dirname = NULL;
00844 dirname_len = 0;
00845 }
00846 basename_len = strlen(basename) + 1;
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
00928 }
00929
00930 file->dir.root = flist_dir;
00931
00932
00933
00934 if (keep_dirlinks && linkname_len && flist) {
00935 STRUCT_STAT st2;
00936 int save_mode = file->mode;
00937 file->mode = S_IFDIR;
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 }
00955
00956 static struct file_struct *send_file_name(int f, struct file_list *flist,
00957 char *fname, STRUCT_STAT *stp,
00958 unsigned short flags)
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
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 }
01007
01008 static void send_if_directory(int f, struct file_list *flist,
01009 struct file_struct *file,
01010 char *fbuf, unsigned int ol)
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 }
01034
01035
01036
01037
01038
01039
01040 static void send_directory(int f, struct file_list *flist,
01041 char *fbuf, int len)
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 }
01092
01093 struct file_list *send_file_list(int f, int argc, char *argv[])
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
01142 is_dot_dir = 0;
01143 } else if (!len || fbuf[len - 1] == '/') {
01144 if (len == 2 && fbuf[0] == '.') {
01145
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
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
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
01269
01270 char *lp = lastpath, *slash = fbuf;
01271 *p = '\0';
01272
01273
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
01341
01342
01343
01344 clean_flist(flist, 0, 0);
01345
01346 send_uid_list(f);
01347
01348
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 }
01363
01364 struct file_list *recv_file_list(int f)
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);
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
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;
01462 }
01463
01464 static int file_compare(struct file_struct **file1, struct file_struct **file2)
01465 {
01466 return f_name_cmp(*file1, *file2);
01467 }
01468
01469
01470
01471 int flist_find(struct file_list *flist, struct file_struct *f)
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
01482
01483
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
01493
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 }
01519
01520
01521
01522
01523
01524 void clear_file(struct file_struct *file, struct file_list *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
01530
01531
01532
01533 file->length = file->dir.depth = 1;
01534 }
01535
01536
01537
01538
01539 struct file_list *flist_new(int with_hlink, char *msg)
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 }
01563
01564
01565
01566
01567 void flist_free(struct file_list *flist)
01568 {
01569 pool_destroy(flist->file_pool);
01570 pool_destroy(flist->hlink_pool);
01571 free(flist->files);
01572 free(flist);
01573 }
01574
01575
01576
01577
01578
01579 static void clean_flist(struct file_list *flist, int strip_root, int no_dups)
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
01612
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
01623
01624
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
01638
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
01660
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;
01677
01678 for (i = flist->low; i <= flist->high; i++) {
01679 struct file_struct *fp, *file = flist->files[i];
01680
01681
01682
01683
01684 if (S_ISDIR(file->mode) && file->dir.depth) {
01685
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
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
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
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 }
01739
01740 static void output_flist(struct file_list *flist)
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 }
01767
01768 enum fnc_state { s_DIR, s_SLASH, s_BASE, s_TRAILING };
01769 enum fnc_type { t_PATH, t_ITEM };
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786 int f_name_cmp(struct file_struct *f1, struct file_struct *f2)
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
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
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 }
01913
01914
01915
01916
01917
01918 char *f_name(struct file_struct *f, char *fbuf)
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 }
01942
01943
01944
01945
01946
01947
01948 struct file_list *get_dirlist(char *dirname, int dlen,
01949 int ignore_filter_rules)
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 }