2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
4 Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 * Generate and receive file lists
24 * @todo Get rid of the string_area optimization. Efficiently
25 * allocating blocks is the responsibility of the system's malloc
26 * library, not of rsync.
28 * @sa http://lists.samba.org/pipermail/rsync/2000-June/002351.html
34 extern struct stats stats
;
37 extern int do_progress
;
39 extern int always_checksum
;
41 extern int cvs_exclude
;
45 extern int one_file_system
;
46 extern int make_backups
;
47 extern int preserve_links
;
48 extern int preserve_hard_links
;
49 extern int preserve_perms
;
50 extern int preserve_devices
;
51 extern int preserve_uid
;
52 extern int preserve_gid
;
53 extern int preserve_times
;
54 extern int relative_paths
;
55 extern int copy_links
;
56 extern int copy_unsafe_links
;
57 extern int remote_version
;
59 extern int sanitize_paths
;
61 extern int read_batch
;
62 extern int write_batch
;
64 static struct exclude_struct
**local_exclude_list
;
66 static struct file_struct null_file
;
68 static void clean_flist(struct file_list
*flist
, int strip_root
);
71 static int show_filelist_p(void)
73 return verbose
&& recurse
&& !am_server
;
76 static void start_filelist_progress(char *kind
)
78 rprintf(FINFO
, "%s ... ", kind
);
79 if ((verbose
> 1) || do_progress
)
85 static void emit_filelist_progress(const struct file_list
*flist
)
87 rprintf(FINFO
, " %d files...\r", flist
->count
);
91 static void maybe_emit_filelist_progress(const struct file_list
*flist
)
93 if (do_progress
&& show_filelist_p() && ((flist
->count
% 100) == 0))
94 emit_filelist_progress(flist
);
98 static void finish_filelist_progress(const struct file_list
*flist
)
101 /* This overwrites the progress line */
102 rprintf(FINFO
, "%d file%sto consider\n",
103 flist
->count
, flist
->count
== 1 ? " " : "s ");
105 rprintf(FINFO
, "done\n");
109 void show_flist_stats(void)
115 static struct string_area
*string_area_new(int size
)
117 struct string_area
*a
;
121 a
= malloc(sizeof(*a
));
123 out_of_memory("string_area_new");
124 a
->current
= a
->base
= malloc(size
);
126 out_of_memory("string_area_new buffer");
127 a
->end
= a
->base
+ size
;
133 static void string_area_free(struct string_area
*a
)
135 struct string_area
*next
;
137 for (; a
; a
= next
) {
143 static char *string_area_malloc(struct string_area
**ap
, int size
)
146 struct string_area
*a
;
148 /* does the request fit into the current space? */
150 if (a
->current
+ size
>= a
->end
) {
151 /* no; get space, move new string_area to front of the list */
152 a
= string_area_new(size
> ARENA_SIZE
? size
: ARENA_SIZE
);
157 /* have space; do the "allocation." */
163 static char *string_area_strdup(struct string_area
**ap
, const char *src
)
165 char *dest
= string_area_malloc(ap
, strlen(src
) + 1);
166 return strcpy(dest
, src
);
169 static void list_file_entry(struct file_struct
*f
)
174 /* this can happen if duplicate names were removed */
177 permstring(perms
, f
->mode
);
179 if (preserve_links
&& S_ISLNK(f
->mode
)) {
180 rprintf(FINFO
, "%s %11.0f %s %s -> %s\n",
182 (double) f
->length
, timestring(f
->modtime
),
185 rprintf(FINFO
, "%s %11.0f %s %s\n",
187 (double) f
->length
, timestring(f
->modtime
),
194 * Stat either a symlink or its referent, depending on the settings of
195 * copy_links, copy_unsafe_links, etc.
197 * @retval -1 on error
199 * @retval 0 for success
201 * @post If @p path is a symlink, then @p linkbuf (of size @c
202 * MAXPATHLEN) contains the symlink target.
204 * @post @p buffer contains information about the link or the
205 * referrent as appropriate, if they exist.
207 int readlink_stat(const char *path
, STRUCT_STAT
* buffer
, char *linkbuf
)
211 return do_stat(path
, buffer
);
213 if (do_lstat(path
, buffer
) == -1) {
216 if (S_ISLNK(buffer
->st_mode
)) {
218 l
= readlink((char *) path
, linkbuf
, MAXPATHLEN
- 1);
222 if (copy_unsafe_links
&& unsafe_symlink(linkbuf
, path
)) {
224 rprintf(FINFO
,"copying unsafe symlink \"%s\" -> \"%s\"\n",
227 return do_stat(path
, buffer
);
232 return do_stat(path
, buffer
);
236 int link_stat(const char *path
, STRUCT_STAT
* buffer
)
240 return do_stat(path
, buffer
);
242 return do_lstat(path
, buffer
);
245 return do_stat(path
, buffer
);
250 This function is used to check if a file should be included/excluded
251 from the list of files based on its name and type etc
253 static int check_exclude_file(int f
, char *fname
, STRUCT_STAT
* st
)
255 extern int delete_excluded
;
257 /* f is set to -1 when calculating deletion file list */
258 if ((f
== -1) && delete_excluded
) {
261 if (check_exclude(fname
, local_exclude_list
, st
)) {
267 /* used by the one_file_system code */
268 static dev_t filesystem_dev
;
270 static void set_filesystem(char *fname
)
273 if (link_stat(fname
, &st
) != 0)
275 filesystem_dev
= st
.st_dev
;
279 static int to_wire_mode(mode_t mode
)
281 if (S_ISLNK(mode
) && (_S_IFLNK
!= 0120000)) {
282 return (mode
& ~(_S_IFMT
)) | 0120000;
287 static mode_t
from_wire_mode(int mode
)
289 if ((mode
& (_S_IFMT
)) == 0120000 && (_S_IFLNK
!= 0120000)) {
290 return (mode
& ~(_S_IFMT
)) | _S_IFLNK
;
292 return (mode_t
) mode
;
296 static void send_directory(int f
, struct file_list
*flist
, char *dir
);
298 static char *flist_dir
;
302 * Make sure @p flist is big enough to hold at least @p flist->count
305 static void flist_expand(struct file_list
*flist
)
307 if (flist
->count
>= flist
->malloced
) {
311 if (flist
->malloced
< 1000)
312 flist
->malloced
+= 1000;
314 flist
->malloced
*= 2;
316 new_bytes
= sizeof(flist
->files
[0]) * flist
->malloced
;
319 new_ptr
= realloc(flist
->files
, new_bytes
);
321 new_ptr
= malloc(new_bytes
);
324 rprintf(FINFO
, "expand file_list to %.0f bytes, did%s move\n",
326 (new_ptr
== flist
->files
) ? " not" : "");
329 flist
->files
= (struct file_struct
**) new_ptr
;
332 out_of_memory("flist_expand");
337 static void send_file_entry(struct file_struct
*file
, int f
,
341 static time_t last_time
;
342 static mode_t last_mode
;
343 static DEV64_T last_rdev
;
344 static uid_t last_uid
;
345 static gid_t last_gid
;
346 static char lastname
[MAXPATHLEN
];
358 io_write_phase
= "send_file_entry";
360 fname
= f_name(file
);
364 if (file
->mode
== last_mode
)
366 if (file
->rdev
== last_rdev
)
368 if (file
->uid
== last_uid
)
370 if (file
->gid
== last_gid
)
372 if (file
->modtime
== last_time
)
376 lastname
[l1
] && (fname
[l1
] == lastname
[l1
]) && (l1
< 255);
378 l2
= strlen(fname
) - l1
;
385 /* we must make sure we don't send a zero flags byte or the other
386 end will terminate the flist transfer */
387 if (flags
== 0 && !S_ISDIR(file
->mode
))
388 flags
|= FLAG_DELETE
;
392 write_byte(f
, flags
);
393 if (flags
& SAME_NAME
)
395 if (flags
& LONG_NAME
)
399 write_buf(f
, fname
+ l1
, l2
);
401 write_longint(f
, file
->length
);
402 if (!(flags
& SAME_TIME
))
403 write_int(f
, (int) file
->modtime
);
404 if (!(flags
& SAME_MODE
))
405 write_int(f
, to_wire_mode(file
->mode
));
406 if (preserve_uid
&& !(flags
& SAME_UID
)) {
408 write_int(f
, (int) file
->uid
);
410 if (preserve_gid
&& !(flags
& SAME_GID
)) {
412 write_int(f
, (int) file
->gid
);
414 if (preserve_devices
&& IS_DEVICE(file
->mode
)
415 && !(flags
& SAME_RDEV
))
416 write_int(f
, (int) file
->rdev
);
419 if (preserve_links
&& S_ISLNK(file
->mode
)) {
420 write_int(f
, strlen(file
->link
));
421 write_buf(f
, file
->link
, strlen(file
->link
));
425 #if SUPPORT_HARD_LINKS
426 if (preserve_hard_links
&& S_ISREG(file
->mode
)) {
427 if (remote_version
< 26) {
428 /* 32-bit dev_t and ino_t */
429 write_int(f
, (int) file
->dev
);
430 write_int(f
, (int) file
->inode
);
432 /* 64-bit dev_t and ino_t */
433 write_longint(f
, file
->dev
);
434 write_longint(f
, file
->inode
);
439 if (always_checksum
) {
440 if (remote_version
< 21) {
441 write_buf(f
, file
->sum
, 2);
443 write_buf(f
, file
->sum
, MD4_SUM_LENGTH
);
447 last_mode
= file
->mode
;
448 last_rdev
= file
->rdev
;
449 last_uid
= file
->uid
;
450 last_gid
= file
->gid
;
451 last_time
= file
->modtime
;
453 strlcpy(lastname
, fname
, MAXPATHLEN
);
454 lastname
[MAXPATHLEN
- 1] = 0;
456 io_write_phase
= "unknown";
461 static void receive_file_entry(struct file_struct
**fptr
,
462 unsigned flags
, int f
)
464 static time_t last_time
;
465 static mode_t last_mode
;
466 static DEV64_T last_rdev
;
467 static uid_t last_uid
;
468 static gid_t last_gid
;
469 static char lastname
[MAXPATHLEN
];
470 char thisname
[MAXPATHLEN
];
471 unsigned int l1
= 0, l2
= 0;
473 struct file_struct
*file
;
475 if (flags
& SAME_NAME
)
478 if (flags
& LONG_NAME
)
483 file
= (struct file_struct
*) malloc(sizeof(*file
));
485 out_of_memory("receive_file_entry");
486 memset((char *) file
, 0, sizeof(*file
));
489 if (l2
>= MAXPATHLEN
- l1
) {
491 "overflow: flags=0x%x l1=%d l2=%d lastname=%s\n",
492 flags
, l1
, l2
, lastname
);
493 overflow("receive_file_entry");
496 strlcpy(thisname
, lastname
, l1
+ 1);
497 read_sbuf(f
, &thisname
[l1
], l2
);
498 thisname
[l1
+ l2
] = 0;
500 strlcpy(lastname
, thisname
, MAXPATHLEN
);
501 lastname
[MAXPATHLEN
- 1] = 0;
503 clean_fname(thisname
);
505 if (sanitize_paths
) {
506 sanitize_path(thisname
, NULL
);
509 if ((p
= strrchr(thisname
, '/'))) {
510 static char *lastdir
;
512 if (lastdir
&& strcmp(thisname
, lastdir
) == 0) {
513 file
->dirname
= lastdir
;
515 file
->dirname
= strdup(thisname
);
516 lastdir
= file
->dirname
;
518 file
->basename
= strdup(p
+ 1);
520 file
->dirname
= NULL
;
521 file
->basename
= strdup(thisname
);
525 out_of_memory("receive_file_entry 1");
529 file
->length
= read_longint(f
);
531 (flags
& SAME_TIME
) ? last_time
: (time_t) read_int(f
);
533 (flags
& SAME_MODE
) ? last_mode
: from_wire_mode(read_int(f
));
536 (flags
& SAME_UID
) ? last_uid
: (uid_t
) read_int(f
);
539 (flags
& SAME_GID
) ? last_gid
: (gid_t
) read_int(f
);
540 if (preserve_devices
&& IS_DEVICE(file
->mode
))
542 (flags
& SAME_RDEV
) ? last_rdev
: (DEV64_T
) read_int(f
);
544 if (preserve_links
&& S_ISLNK(file
->mode
)) {
547 rprintf(FERROR
, "overflow: l=%d\n", l
);
548 overflow("receive_file_entry");
550 file
->link
= (char *) malloc(l
+ 1);
552 out_of_memory("receive_file_entry 2");
553 read_sbuf(f
, file
->link
, l
);
554 if (sanitize_paths
) {
555 sanitize_path(file
->link
, file
->dirname
);
558 #if SUPPORT_HARD_LINKS
559 if (preserve_hard_links
&& S_ISREG(file
->mode
)) {
560 if (remote_version
< 26) {
561 file
->dev
= read_int(f
);
562 file
->inode
= read_int(f
);
564 file
->dev
= read_longint(f
);
565 file
->inode
= read_longint(f
);
570 if (always_checksum
) {
571 file
->sum
= (char *) malloc(MD4_SUM_LENGTH
);
573 out_of_memory("md4 sum");
574 if (remote_version
< 21) {
575 read_buf(f
, file
->sum
, 2);
577 read_buf(f
, file
->sum
, MD4_SUM_LENGTH
);
581 last_mode
= file
->mode
;
582 last_rdev
= file
->rdev
;
583 last_uid
= file
->uid
;
584 last_gid
= file
->gid
;
585 last_time
= file
->modtime
;
587 if (!preserve_perms
) {
588 extern int orig_umask
;
589 /* set an appropriate set of permissions based on original
590 permissions and umask. This emulates what GNU cp does */
591 file
->mode
&= ~orig_umask
;
596 /* determine if a file in a different filesstem should be skipped
597 when one_file_system is set. We bascally only want to include
598 the mount points - but they can be hard to find! */
599 static int skip_filesystem(char *fname
, STRUCT_STAT
* st
)
602 char *p
= strrchr(fname
, '/');
604 /* skip all but directories */
605 if (!S_ISDIR(st
->st_mode
))
608 /* if its not a subdirectory then allow */
613 if (link_stat(fname
, &st2
)) {
619 return (st2
.st_dev
!= filesystem_dev
);
622 #define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
623 /* IRIX cc cares that the operands to the ternary have the same type. */
624 #define MALLOC(ap, i) (ap ? (void*) string_area_malloc(ap, i) : malloc(i))
627 * Create a file_struct for a named file by reading its stat()
628 * information and performing extensive checks against global
631 * @return the new file, or NULL if there was an error or this file
632 * should be excluded.
634 * @todo There is a small optimization opportunity here to avoid
635 * stat()ing the file in some circumstances, which has a certain cost.
636 * We are called immediately after doing readdir(), and so we may
637 * already know the d_type of the file. We could for example avoid
638 * statting directories if we're not recursing, but this is not a very
639 * important case. Some systems may not have d_type.
641 struct file_struct
*make_file(int f
, char *fname
, struct string_area
**ap
,
644 struct file_struct
*file
;
646 char sum
[SUM_LENGTH
];
648 char cleaned_name
[MAXPATHLEN
];
649 char linkbuf
[MAXPATHLEN
];
650 extern int module_id
;
652 strlcpy(cleaned_name
, fname
, MAXPATHLEN
);
653 cleaned_name
[MAXPATHLEN
- 1] = 0;
654 clean_fname(cleaned_name
);
655 if (sanitize_paths
) {
656 sanitize_path(cleaned_name
, NULL
);
658 fname
= cleaned_name
;
660 memset(sum
, 0, SUM_LENGTH
);
662 if (readlink_stat(fname
, &st
, linkbuf
) != 0) {
663 int save_errno
= errno
;
664 if ((errno
== ENOENT
) && !noexcludes
) {
665 /* either symlink pointing nowhere or file that
666 * was removed during rsync run; see if excluded
667 * before reporting an error */
668 memset((char *) &st
, 0, sizeof(st
));
669 if (check_exclude_file(f
, fname
, &st
)) {
670 /* file is excluded anyway, ignore silently */
675 rprintf(FERROR
, "readlink %s: %s\n",
676 fname
, strerror(save_errno
));
680 /* we use noexcludes from backup.c */
684 if (S_ISDIR(st
.st_mode
) && !recurse
) {
685 rprintf(FINFO
, "skipping directory %s\n", fname
);
689 if (one_file_system
&& st
.st_dev
!= filesystem_dev
) {
690 if (skip_filesystem(fname
, &st
))
694 if (check_exclude_file(f
, fname
, &st
))
698 if (lp_ignore_nonreadable(module_id
) && access(fname
, R_OK
) != 0)
704 rprintf(FINFO
, "make_file(%d,%s)\n", f
, fname
);
706 file
= (struct file_struct
*) malloc(sizeof(*file
));
708 out_of_memory("make_file");
709 memset((char *) file
, 0, sizeof(*file
));
711 if ((p
= strrchr(fname
, '/'))) {
712 static char *lastdir
;
714 if (lastdir
&& strcmp(fname
, lastdir
) == 0) {
715 file
->dirname
= lastdir
;
717 file
->dirname
= strdup(fname
);
718 lastdir
= file
->dirname
;
720 file
->basename
= STRDUP(ap
, p
+ 1);
723 file
->dirname
= NULL
;
724 file
->basename
= STRDUP(ap
, fname
);
727 file
->modtime
= st
.st_mtime
;
728 file
->length
= st
.st_size
;
729 file
->mode
= st
.st_mode
;
730 file
->uid
= st
.st_uid
;
731 file
->gid
= st
.st_gid
;
732 file
->dev
= st
.st_dev
;
733 file
->inode
= st
.st_ino
;
734 #ifdef HAVE_STRUCT_STAT_ST_RDEV
735 file
->rdev
= st
.st_rdev
;
739 if (S_ISLNK(st
.st_mode
)) {
740 file
->link
= STRDUP(ap
, linkbuf
);
744 if (always_checksum
) {
745 file
->sum
= (char *) MALLOC(ap
, MD4_SUM_LENGTH
);
747 out_of_memory("md4 sum");
748 /* drat. we have to provide a null checksum for non-regular
749 files in order to be compatible with earlier versions
751 if (S_ISREG(st
.st_mode
)) {
752 file_checksum(fname
, file
->sum
, st
.st_size
);
754 memset(file
->sum
, 0, MD4_SUM_LENGTH
);
759 static char *lastdir
;
760 if (lastdir
&& strcmp(lastdir
, flist_dir
) == 0) {
761 file
->basedir
= lastdir
;
763 file
->basedir
= strdup(flist_dir
);
764 lastdir
= file
->basedir
;
767 file
->basedir
= NULL
;
770 if (!S_ISDIR(st
.st_mode
))
771 stats
.total_size
+= st
.st_size
;
778 void send_file_name(int f
, struct file_list
*flist
, char *fname
,
779 int recursive
, unsigned base_flags
)
781 struct file_struct
*file
;
783 file
= make_file(f
, fname
, &flist
->string_area
, 0);
788 maybe_emit_filelist_progress(flist
);
792 if (write_batch
) /* dw */
793 file
->flags
= FLAG_DELETE
;
795 if (strcmp(file
->basename
, "")) {
796 flist
->files
[flist
->count
++] = file
;
797 send_file_entry(file
, f
, base_flags
);
800 if (S_ISDIR(file
->mode
) && recursive
) {
801 struct exclude_struct
**last_exclude_list
=
803 send_directory(f
, flist
, f_name(file
));
804 local_exclude_list
= last_exclude_list
;
811 static void send_directory(int f
, struct file_list
*flist
, char *dir
)
815 char fname
[MAXPATHLEN
];
822 rprintf(FERROR
, "opendir(%s): %s\n", dir
, strerror(errno
));
826 strlcpy(fname
, dir
, MAXPATHLEN
);
828 if (fname
[l
- 1] != '/') {
829 if (l
== MAXPATHLEN
- 1) {
832 "skipping long-named directory %s\n",
837 strlcat(fname
, "/", MAXPATHLEN
);
840 p
= fname
+ strlen(fname
);
842 local_exclude_list
= NULL
;
845 if (strlen(fname
) + strlen(".cvsignore") <= MAXPATHLEN
- 1) {
846 strcpy(p
, ".cvsignore");
848 make_exclude_list(fname
, NULL
, 0, 0);
852 "cannot cvs-exclude in long-named directory %s\n",
857 for (di
= readdir(d
); di
; di
= readdir(d
)) {
858 char *dname
= d_name(di
);
859 if (strcmp(dname
, ".") == 0 || strcmp(dname
, "..") == 0)
861 strlcpy(p
, dname
, MAXPATHLEN
- l
);
862 send_file_name(f
, flist
, fname
, recurse
, 0);
865 if (local_exclude_list
) {
866 add_exclude_list("!", &local_exclude_list
, 0);
875 * I <b>think</b> f==-1 means that the list should just be built in
876 * memory and not transmitted. But who can tell? -- mbp
878 struct file_list
*send_file_list(int f
, int argc
, char *argv
[])
882 char *p
, *dir
, *olddir
;
883 char lastpath
[MAXPATHLEN
] = "";
884 struct file_list
*flist
;
887 if (show_filelist_p() && f
!= -1)
888 start_filelist_progress("building file list");
890 start_write
= stats
.total_written
;
895 io_start_buffering(f
);
898 for (i
= 0; i
< argc
; i
++) {
899 char fname2
[MAXPATHLEN
];
900 char *fname
= fname2
;
902 strlcpy(fname
, argv
[i
], MAXPATHLEN
);
905 if (l
!= 1 && fname
[l
- 1] == '/') {
906 if ((l
== 2) && (fname
[0] == '.')) {
907 /* Turn ./ into just . rather than ./.
908 This was put in to avoid a problem with
909 rsync -aR --delete from ./
910 The send_file_name() below of ./ was
911 mysteriously preventing deletes */
914 strlcat(fname
, ".", MAXPATHLEN
);
918 if (link_stat(fname
, &st
) != 0) {
921 rprintf(FERROR
, "link_stat %s : %s\n",
922 fname
, strerror(errno
));
927 if (S_ISDIR(st
.st_mode
) && !recurse
) {
928 rprintf(FINFO
, "skipping directory %s\n", fname
);
935 if (!relative_paths
) {
936 p
= strrchr(fname
, '/');
945 } else if (f
!= -1 && (p
= strrchr(fname
, '/'))) {
946 /* this ensures we send the intermediate directories,
947 thus getting their permissions right */
949 if (strcmp(lastpath
, fname
)) {
950 strlcpy(lastpath
, fname
, sizeof(lastpath
));
952 for (p
= fname
+ 1; (p
= strchr(p
, '/'));
954 int copy_links_saved
= copy_links
;
955 int recurse_saved
= recurse
;
957 copy_links
= copy_unsafe_links
;
958 /* set recurse to 1 to prevent make_file
959 from ignoring directory, but still
960 turn off the recursive parameter to
963 send_file_name(f
, flist
, fname
, 0,
965 copy_links
= copy_links_saved
;
966 recurse
= recurse_saved
;
978 olddir
= push_dir(dir
, 1);
982 rprintf(FERROR
, "push_dir %s : %s\n",
983 dir
, strerror(errno
));
991 set_filesystem(fname
);
993 send_file_name(f
, flist
, fname
, recurse
, FLAG_DELETE
);
995 if (olddir
!= NULL
) {
997 if (pop_dir(olddir
) != 0) {
998 rprintf(FERROR
, "pop_dir %s : %s\n",
999 dir
, strerror(errno
));
1000 exit_cleanup(RERR_FILESELECT
);
1006 send_file_entry(NULL
, f
, 0);
1009 if (show_filelist_p() && f
!= -1) {
1010 finish_filelist_progress(flist
);
1013 clean_flist(flist
, 0);
1015 /* now send the uid/gid list. This was introduced in protocol
1017 if (f
!= -1 && remote_version
>= 15) {
1021 /* if protocol version is >= 17 then send the io_error flag */
1022 if (f
!= -1 && remote_version
>= 17) {
1023 extern int module_id
;
1024 write_int(f
, lp_ignore_errors(module_id
) ? 0 : io_error
);
1029 stats
.flist_size
= stats
.total_written
- start_write
;
1030 stats
.num_files
= flist
->count
;
1031 if (write_batch
) /* dw */
1032 write_batch_flist_info(flist
->count
, flist
->files
);
1036 rprintf(FINFO
, "send_file_list done\n");
1042 struct file_list
*recv_file_list(int f
)
1044 struct file_list
*flist
;
1045 unsigned char flags
;
1047 extern int list_only
;
1049 if (show_filelist_p())
1050 start_filelist_progress("receiving file list");
1052 start_read
= stats
.total_read
;
1054 flist
= (struct file_list
*) malloc(sizeof(flist
[0]));
1059 flist
->malloced
= 1000;
1061 (struct file_struct
**) malloc(sizeof(flist
->files
[0]) *
1067 for (flags
= read_byte(f
); flags
; flags
= read_byte(f
)) {
1068 int i
= flist
->count
;
1070 flist_expand(flist
);
1072 receive_file_entry(&flist
->files
[i
], flags
, f
);
1074 if (S_ISREG(flist
->files
[i
]->mode
))
1075 stats
.total_size
+= flist
->files
[i
]->length
;
1079 maybe_emit_filelist_progress(flist
);
1082 rprintf(FINFO
, "recv_file_name(%s)\n",
1083 f_name(flist
->files
[i
]));
1088 rprintf(FINFO
, "received %d names\n", flist
->count
);
1090 clean_flist(flist
, relative_paths
);
1092 if (show_filelist_p()) {
1093 finish_filelist_progress(flist
);
1096 /* now recv the uid/gid list. This was introduced in protocol version 15 */
1097 if (f
!= -1 && remote_version
>= 15) {
1098 recv_uid_list(f
, flist
);
1101 /* if protocol version is >= 17 then recv the io_error flag */
1102 if (f
!= -1 && remote_version
>= 17 && !read_batch
) { /* dw-added readbatch */
1103 extern int module_id
;
1104 extern int ignore_errors
;
1105 if (lp_ignore_errors(module_id
) || ignore_errors
) {
1108 io_error
|= read_int(f
);
1114 for (i
= 0; i
< flist
->count
; i
++) {
1115 list_file_entry(flist
->files
[i
]);
1121 rprintf(FINFO
, "recv_file_list done\n");
1123 stats
.flist_size
= stats
.total_read
- start_read
;
1124 stats
.num_files
= flist
->count
;
1129 out_of_memory("recv_file_list");
1130 return NULL
; /* not reached */
1135 * XXX: This is currently the hottest function while building the file
1136 * list, because building f_name()s every time is expensive.
1138 int file_compare(struct file_struct
**f1
, struct file_struct
**f2
)
1140 if (!(*f1
)->basename
&& !(*f2
)->basename
)
1142 if (!(*f1
)->basename
)
1144 if (!(*f2
)->basename
)
1146 if ((*f1
)->dirname
== (*f2
)->dirname
)
1147 return u_strcmp((*f1
)->basename
, (*f2
)->basename
);
1148 return u_strcmp(f_name(*f1
), f_name(*f2
));
1152 int flist_find(struct file_list
*flist
, struct file_struct
*f
)
1154 int low
= 0, high
= flist
->count
- 1;
1156 while (high
>= 0 && !flist
->files
[high
]->basename
) high
--;
1161 while (low
!= high
) {
1162 int mid
= (low
+ high
) / 2;
1164 file_compare(&flist
->files
[flist_up(flist
, mid
)], &f
);
1166 return flist_up(flist
, mid
);
1174 if (file_compare(&flist
->files
[flist_up(flist
, low
)], &f
) == 0)
1175 return flist_up(flist
, low
);
1183 void free_file(struct file_struct
*file
)
1188 free(file
->basename
);
1198 * allocate a new file list
1200 struct file_list
*flist_new(void)
1202 struct file_list
*flist
;
1204 flist
= (struct file_list
*) malloc(sizeof(flist
[0]));
1206 out_of_memory("send_file_list");
1209 flist
->malloced
= 0;
1210 flist
->files
= NULL
;
1213 flist
->string_area
= string_area_new(0);
1215 flist
->string_area
= NULL
;
1221 * free up all elements in a flist
1223 void flist_free(struct file_list
*flist
)
1226 for (i
= 1; i
< flist
->count
; i
++) {
1227 if (!flist
->string_area
)
1228 free_file(flist
->files
[i
]);
1229 free(flist
->files
[i
]);
1231 /* FIXME: I don't think we generally need to blank the flist
1232 * since it's about to be freed. This will just cause more
1233 * memory traffic. If you want a freed-memory debugger, you
1234 * know where to get it. */
1235 memset((char *) flist
->files
, 0,
1236 sizeof(flist
->files
[0]) * flist
->count
);
1238 if (flist
->string_area
)
1239 string_area_free(flist
->string_area
);
1240 memset((char *) flist
, 0, sizeof(*flist
));
1246 * This routine ensures we don't have any duplicate names in our file list.
1247 * duplicate names can cause corruption because of the pipelining
1249 static void clean_flist(struct file_list
*flist
, int strip_root
)
1252 char *name
, *prev_name
= NULL
;
1254 if (!flist
|| flist
->count
== 0)
1257 qsort(flist
->files
, flist
->count
,
1258 sizeof(flist
->files
[0]), (int (*)()) file_compare
);
1260 for (i
= 0; i
< flist
->count
; i
++) {
1261 if (flist
->files
[i
]->basename
) {
1262 prev_name
= f_name(flist
->files
[i
]);
1266 while (++i
< flist
->count
) {
1267 if (!flist
->files
[i
]->basename
)
1269 name
= f_name(flist
->files
[i
]);
1270 if (strcmp(name
, prev_name
) == 0) {
1271 if (verbose
> 1 && !am_server
) {
1273 "removing duplicate name %s from file list %d\n",
1276 /* it's not great that the flist knows the semantics of
1277 * the file memory usage, but i'd rather not add a flag
1278 * byte to that struct.
1279 * XXX can i use a bit in the flags field? */
1280 if (flist
->string_area
)
1281 flist
->files
[i
][0] = null_file
;
1283 free_file(flist
->files
[i
]);
1289 /* we need to strip off the root directory in the case
1290 of relative paths, but this must be done _after_
1291 the sorting phase */
1292 for (i
= 0; i
< flist
->count
; i
++) {
1293 if (flist
->files
[i
]->dirname
&&
1294 flist
->files
[i
]->dirname
[0] == '/') {
1295 memmove(&flist
->files
[i
]->dirname
[0],
1296 &flist
->files
[i
]->dirname
[1],
1297 strlen(flist
->files
[i
]->dirname
));
1300 if (flist
->files
[i
]->dirname
&&
1301 !flist
->files
[i
]->dirname
[0]) {
1302 flist
->files
[i
]->dirname
= NULL
;
1310 for (i
= 0; i
< flist
->count
; i
++) {
1311 rprintf(FINFO
, "[%d] i=%d %s %s mode=0%o len=%.0f\n",
1313 NS(flist
->files
[i
]->dirname
),
1314 NS(flist
->files
[i
]->basename
),
1315 (int) flist
->files
[i
]->mode
,
1316 (double) flist
->files
[i
]->length
);
1322 * return the full filename of a flist entry
1324 * This function is too expensive at the moment, because it copies
1325 * strings when often we only want to compare them. In any case,
1326 * using strlcat is silly because it will walk the string repeatedly.
1328 char *f_name(struct file_struct
*f
)
1330 static char names
[10][MAXPATHLEN
];
1334 if (!f
|| !f
->basename
)
1342 off
= strlcpy(p
, f
->dirname
, MAXPATHLEN
);
1343 off
+= strlcpy(p
+ off
, "/", MAXPATHLEN
- off
);
1344 off
+= strlcpy(p
+ off
, f
->basename
, MAXPATHLEN
- off
);
1346 strlcpy(p
, f
->basename
, MAXPATHLEN
);