2 Copyright (C) Andrew Tridgell 1996
3 Copyright (C) Paul Mackerras 1996
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* generate and receive file lists */
24 extern struct stats stats
;
28 extern int always_checksum
;
30 extern int cvs_exclude
;
34 extern int one_file_system
;
35 extern int make_backups
;
36 extern int preserve_links
;
37 extern int preserve_hard_links
;
38 extern int preserve_perms
;
39 extern int preserve_devices
;
40 extern int preserve_uid
;
41 extern int preserve_gid
;
42 extern int preserve_times
;
43 extern int relative_paths
;
44 extern int copy_links
;
45 extern int copy_unsafe_links
;
46 extern int remote_version
;
48 extern int sanitize_paths
;
50 extern int read_batch
;
51 extern int write_batch
;
53 static char topsrcname
[MAXPATHLEN
];
55 static struct exclude_struct
**local_exclude_list
;
57 static struct file_struct null_file
;
59 static void clean_flist(struct file_list
*flist
, int strip_root
);
61 static struct string_area
*string_area_new(int size
)
63 struct string_area
*a
;
65 if (size
<= 0) size
= ARENA_SIZE
;
66 a
= malloc(sizeof(*a
));
67 if (!a
) out_of_memory("string_area_new");
68 a
->current
= a
->base
= malloc(size
);
69 if (!a
->current
) out_of_memory("string_area_new buffer");
70 a
->end
= a
->base
+ size
;
76 static void string_area_free(struct string_area
*a
)
78 struct string_area
*next
;
80 for ( ; a
; a
= next
) {
86 static char *string_area_malloc(struct string_area
**ap
, int size
)
89 struct string_area
*a
;
91 /* does the request fit into the current space? */
93 if (a
->current
+ size
>= a
->end
) {
94 /* no; get space, move new string_area to front of the list */
95 a
= string_area_new(size
> ARENA_SIZE
? size
: ARENA_SIZE
);
100 /* have space; do the "allocation." */
106 static char *string_area_strdup(struct string_area
**ap
, const char *src
)
108 char* dest
= string_area_malloc(ap
, strlen(src
) + 1);
109 return strcpy(dest
, src
);
112 static void list_file_entry(struct file_struct
*f
)
114 char perms
[11] = "----------";
115 char *perm_map
= "rwxrwxrwx";
119 /* this can happen if duplicate names were removed */
123 if (f
->mode
& (1<<i
)) perms
[9-i
] = perm_map
[8-i
];
125 if (S_ISLNK(f
->mode
)) perms
[0] = 'l';
126 if (S_ISDIR(f
->mode
)) perms
[0] = 'd';
127 if (S_ISBLK(f
->mode
)) perms
[0] = 'b';
128 if (S_ISCHR(f
->mode
)) perms
[0] = 'c';
129 if (S_ISSOCK(f
->mode
)) perms
[0] = 's';
130 if (S_ISFIFO(f
->mode
)) perms
[0] = 'p';
132 if (preserve_links
&& S_ISLNK(f
->mode
)) {
133 rprintf(FINFO
,"%s %11.0f %s %s -> %s\n",
135 (double)f
->length
, timestring(f
->modtime
),
138 rprintf(FINFO
,"%s %11.0f %s %s\n",
140 (double)f
->length
, timestring(f
->modtime
), f_name(f
));
145 int readlink_stat(const char *Path
, STRUCT_STAT
*Buffer
, char *Linkbuf
)
149 return do_stat(Path
, Buffer
);
151 if (do_lstat(Path
, Buffer
) == -1) {
154 if (S_ISLNK(Buffer
->st_mode
)) {
156 if ((l
= readlink((char *) Path
, Linkbuf
, MAXPATHLEN
-1))== -1) {
160 if (copy_unsafe_links
&& (topsrcname
[0] != '\0') &&
161 unsafe_symlink(Linkbuf
, topsrcname
)) {
162 return do_stat(Path
, Buffer
);
167 return do_stat(Path
, Buffer
);
171 int link_stat(const char *Path
, STRUCT_STAT
*Buffer
)
175 return do_stat(Path
, Buffer
);
177 return do_lstat(Path
, Buffer
);
180 return do_stat(Path
, Buffer
);
185 This function is used to check if a file should be included/excluded
186 from the list of files based on its name and type etc
188 static int match_file_name(char *fname
,STRUCT_STAT
*st
)
190 if (check_exclude(fname
,local_exclude_list
,st
)) {
196 /* used by the one_file_system code */
197 static dev_t filesystem_dev
;
199 static void set_filesystem(char *fname
)
202 if (link_stat(fname
,&st
) != 0) return;
203 filesystem_dev
= st
.st_dev
;
207 static int to_wire_mode(mode_t mode
)
209 if (S_ISLNK(mode
) && (_S_IFLNK
!= 0120000)) {
210 return (mode
& ~(_S_IFMT
)) | 0120000;
215 static mode_t
from_wire_mode(int mode
)
217 if ((mode
& (_S_IFMT
)) == 0120000 && (_S_IFLNK
!= 0120000)) {
218 return (mode
& ~(_S_IFMT
)) | _S_IFLNK
;
224 static void send_directory(int f
,struct file_list
*flist
,char *dir
);
226 static char *flist_dir
;
229 static void send_file_entry(struct file_struct
*file
,int f
,unsigned base_flags
)
232 static time_t last_time
;
233 static mode_t last_mode
;
234 static dev_t last_rdev
;
235 static uid_t last_uid
;
236 static gid_t last_gid
;
237 static char lastname
[MAXPATHLEN
];
248 fname
= f_name(file
);
252 if (file
->mode
== last_mode
) flags
|= SAME_MODE
;
253 if (file
->rdev
== last_rdev
) flags
|= SAME_RDEV
;
254 if (file
->uid
== last_uid
) flags
|= SAME_UID
;
255 if (file
->gid
== last_gid
) flags
|= SAME_GID
;
256 if (file
->modtime
== last_time
) flags
|= SAME_TIME
;
258 for (l1
=0;lastname
[l1
] && (fname
[l1
] == lastname
[l1
]) && (l1
< 255);l1
++) ;
259 l2
= strlen(fname
) - l1
;
261 if (l1
> 0) flags
|= SAME_NAME
;
262 if (l2
> 255) flags
|= LONG_NAME
;
264 /* we must make sure we don't send a zero flags byte or the other
265 end will terminate the flist transfer */
266 if (flags
== 0 && !S_ISDIR(file
->mode
)) flags
|= FLAG_DELETE
;
267 if (flags
== 0) flags
|= LONG_NAME
;
270 if (flags
& SAME_NAME
)
272 if (flags
& LONG_NAME
)
276 write_buf(f
,fname
+l1
,l2
);
278 write_longint(f
,file
->length
);
279 if (!(flags
& SAME_TIME
))
280 write_int(f
,(int)file
->modtime
);
281 if (!(flags
& SAME_MODE
))
282 write_int(f
,to_wire_mode(file
->mode
));
283 if (preserve_uid
&& !(flags
& SAME_UID
)) {
285 write_int(f
,(int)file
->uid
);
287 if (preserve_gid
&& !(flags
& SAME_GID
)) {
289 write_int(f
,(int)file
->gid
);
291 if (preserve_devices
&& IS_DEVICE(file
->mode
) && !(flags
& SAME_RDEV
))
292 write_int(f
,(int)file
->rdev
);
295 if (preserve_links
&& S_ISLNK(file
->mode
)) {
296 write_int(f
,strlen(file
->link
));
297 write_buf(f
,file
->link
,strlen(file
->link
));
301 #if SUPPORT_HARD_LINKS
302 if (preserve_hard_links
&& S_ISREG(file
->mode
)) {
303 write_int(f
,(int)file
->dev
);
304 write_int(f
,(int)file
->inode
);
308 if (always_checksum
) {
309 if (remote_version
< 21) {
310 write_buf(f
,file
->sum
,2);
312 write_buf(f
,file
->sum
,MD4_SUM_LENGTH
);
316 last_mode
= file
->mode
;
317 last_rdev
= file
->rdev
;
318 last_uid
= file
->uid
;
319 last_gid
= file
->gid
;
320 last_time
= file
->modtime
;
322 strlcpy(lastname
,fname
,MAXPATHLEN
);
323 lastname
[MAXPATHLEN
-1] = 0;
328 static void receive_file_entry(struct file_struct
**fptr
,
329 unsigned flags
,int f
)
331 static time_t last_time
;
332 static mode_t last_mode
;
333 static dev_t last_rdev
;
334 static uid_t last_uid
;
335 static gid_t last_gid
;
336 static char lastname
[MAXPATHLEN
];
337 char thisname
[MAXPATHLEN
];
340 struct file_struct
*file
;
342 if (flags
& SAME_NAME
)
345 if (flags
& LONG_NAME
)
350 file
= (struct file_struct
*)malloc(sizeof(*file
));
351 if (!file
) out_of_memory("receive_file_entry");
352 memset((char *)file
, 0, sizeof(*file
));
355 if (l2
>= MAXPATHLEN
-l1
) {
356 rprintf(FERROR
,"overflow: flags=0x%x l1=%d l2=%d lastname=%s\n",
357 flags
, l1
, l2
, lastname
);
358 overflow("receive_file_entry");
361 strlcpy(thisname
,lastname
,l1
+1);
362 read_sbuf(f
,&thisname
[l1
],l2
);
365 strlcpy(lastname
,thisname
,MAXPATHLEN
);
366 lastname
[MAXPATHLEN
-1] = 0;
368 clean_fname(thisname
);
370 if (sanitize_paths
) {
371 sanitize_path(thisname
, NULL
);
374 if ((p
= strrchr(thisname
,'/'))) {
375 static char *lastdir
;
377 if (lastdir
&& strcmp(thisname
, lastdir
)==0) {
378 file
->dirname
= lastdir
;
380 file
->dirname
= strdup(thisname
);
381 lastdir
= file
->dirname
;
383 file
->basename
= strdup(p
+1);
385 file
->dirname
= NULL
;
386 file
->basename
= strdup(thisname
);
389 if (!file
->basename
) out_of_memory("receive_file_entry 1");
393 file
->length
= read_longint(f
);
394 file
->modtime
= (flags
& SAME_TIME
) ? last_time
: (time_t)read_int(f
);
395 file
->mode
= (flags
& SAME_MODE
) ? last_mode
: from_wire_mode(read_int(f
));
397 file
->uid
= (flags
& SAME_UID
) ? last_uid
: (uid_t
)read_int(f
);
399 file
->gid
= (flags
& SAME_GID
) ? last_gid
: (gid_t
)read_int(f
);
400 if (preserve_devices
&& IS_DEVICE(file
->mode
))
401 file
->rdev
= (flags
& SAME_RDEV
) ? last_rdev
: (dev_t
)read_int(f
);
403 if (preserve_links
&& S_ISLNK(file
->mode
)) {
405 file
->link
= (char *)malloc(l
+1);
406 if (!file
->link
) out_of_memory("receive_file_entry 2");
407 read_sbuf(f
,file
->link
,l
);
408 if (sanitize_paths
) {
409 sanitize_path(file
->link
, file
->dirname
);
413 #if SUPPORT_HARD_LINKS
414 if (preserve_hard_links
&& S_ISREG(file
->mode
)) {
415 file
->dev
= read_int(f
);
416 file
->inode
= read_int(f
);
420 if (always_checksum
) {
421 file
->sum
= (char *)malloc(MD4_SUM_LENGTH
);
422 if (!file
->sum
) out_of_memory("md4 sum");
423 if (remote_version
< 21) {
424 read_buf(f
,file
->sum
,2);
426 read_buf(f
,file
->sum
,MD4_SUM_LENGTH
);
430 last_mode
= file
->mode
;
431 last_rdev
= file
->rdev
;
432 last_uid
= file
->uid
;
433 last_gid
= file
->gid
;
434 last_time
= file
->modtime
;
436 if (!preserve_perms
) {
437 extern int orig_umask
;
438 /* set an appropriate set of permissions based on original
439 permissions and umask. This emulates what GNU cp does */
440 file
->mode
&= ~orig_umask
;
445 /* determine if a file in a different filesstem should be skipped
446 when one_file_system is set. We bascally only want to include
447 the mount points - but they can be hard to find! */
448 static int skip_filesystem(char *fname
, STRUCT_STAT
*st
)
451 char *p
= strrchr(fname
, '/');
453 /* skip all but directories */
454 if (!S_ISDIR(st
->st_mode
)) return 1;
456 /* if its not a subdirectory then allow */
460 if (link_stat(fname
, &st2
)) {
466 return (st2
.st_dev
!= filesystem_dev
);
469 #define STRDUP(ap, p) (ap ? string_area_strdup(ap, p) : strdup(p))
470 #define MALLOC(ap, i) (ap ? string_area_malloc(ap, i) : malloc(i))
472 /* create a file_struct for a named file */
473 struct file_struct
*make_file(int f
, char *fname
, struct string_area
**ap
,
476 struct file_struct
*file
;
478 char sum
[SUM_LENGTH
];
480 char cleaned_name
[MAXPATHLEN
];
481 char linkbuf
[MAXPATHLEN
];
482 extern int delete_excluded
;
483 extern int module_id
;
485 strlcpy(cleaned_name
, fname
, MAXPATHLEN
);
486 cleaned_name
[MAXPATHLEN
-1] = 0;
487 clean_fname(cleaned_name
);
488 if (sanitize_paths
) {
489 sanitize_path(cleaned_name
, NULL
);
491 fname
= cleaned_name
;
493 memset(sum
,0,SUM_LENGTH
);
495 if (readlink_stat(fname
,&st
,linkbuf
) != 0) {
497 rprintf(FERROR
,"readlink %s: %s\n",
498 fname
,strerror(errno
));
502 /* we use noexcludes from backup.c */
503 if (noexcludes
) goto skip_excludes
;
505 if (S_ISDIR(st
.st_mode
) && !recurse
) {
506 rprintf(FINFO
,"skipping directory %s\n",fname
);
510 if (one_file_system
&& st
.st_dev
!= filesystem_dev
) {
511 if (skip_filesystem(fname
, &st
))
515 /* f is set to -1 when calculating deletion file list */
516 if (((f
!= -1) || !delete_excluded
) && !match_file_name(fname
,&st
))
520 if (lp_ignore_nonreadable(module_id
) && access(fname
, R_OK
) != 0)
526 rprintf(FINFO
,"make_file(%d,%s)\n",f
,fname
);
528 file
= (struct file_struct
*)malloc(sizeof(*file
));
529 if (!file
) out_of_memory("make_file");
530 memset((char *)file
,0,sizeof(*file
));
532 if ((p
= strrchr(fname
,'/'))) {
533 static char *lastdir
;
535 if (lastdir
&& strcmp(fname
, lastdir
)==0) {
536 file
->dirname
= lastdir
;
538 file
->dirname
= strdup(fname
);
539 lastdir
= file
->dirname
;
541 file
->basename
= STRDUP(ap
, p
+1);
544 file
->dirname
= NULL
;
545 file
->basename
= STRDUP(ap
, fname
);
548 file
->modtime
= st
.st_mtime
;
549 file
->length
= st
.st_size
;
550 file
->mode
= st
.st_mode
;
551 file
->uid
= st
.st_uid
;
552 file
->gid
= st
.st_gid
;
553 file
->dev
= st
.st_dev
;
554 file
->inode
= st
.st_ino
;
556 file
->rdev
= st
.st_rdev
;
560 if (S_ISLNK(st
.st_mode
)) {
561 file
->link
= STRDUP(ap
, linkbuf
);
565 if (always_checksum
) {
566 file
->sum
= (char *)MALLOC(ap
, MD4_SUM_LENGTH
);
567 if (!file
->sum
) out_of_memory("md4 sum");
568 /* drat. we have to provide a null checksum for non-regular
569 files in order to be compatible with earlier versions
571 if (S_ISREG(st
.st_mode
)) {
572 file_checksum(fname
,file
->sum
,st
.st_size
);
574 memset(file
->sum
, 0, MD4_SUM_LENGTH
);
579 static char *lastdir
;
580 if (lastdir
&& strcmp(lastdir
, flist_dir
)==0) {
581 file
->basedir
= lastdir
;
583 file
->basedir
= strdup(flist_dir
);
584 lastdir
= file
->basedir
;
587 file
->basedir
= NULL
;
590 if (!S_ISDIR(st
.st_mode
))
591 stats
.total_size
+= st
.st_size
;
598 void send_file_name(int f
,struct file_list
*flist
,char *fname
,
599 int recursive
, unsigned base_flags
)
601 struct file_struct
*file
;
603 file
= make_file(f
,fname
, &flist
->string_area
, 0);
607 if (flist
->count
>= flist
->malloced
) {
608 if (flist
->malloced
< 1000)
609 flist
->malloced
+= 1000;
611 flist
->malloced
*= 2;
612 flist
->files
= (struct file_struct
**)realloc(flist
->files
,
613 sizeof(flist
->files
[0])*
616 out_of_memory("send_file_name");
619 if (write_batch
) /* dw */
620 file
->flags
= FLAG_DELETE
;
622 if (strcmp(file
->basename
,"")) {
623 flist
->files
[flist
->count
++] = file
;
624 send_file_entry(file
,f
,base_flags
);
627 if (S_ISDIR(file
->mode
) && recursive
) {
628 struct exclude_struct
**last_exclude_list
= local_exclude_list
;
629 send_directory(f
,flist
,f_name(file
));
630 local_exclude_list
= last_exclude_list
;
637 static void send_directory(int f
,struct file_list
*flist
,char *dir
)
641 char fname
[MAXPATHLEN
];
648 rprintf(FERROR
,"opendir(%s): %s\n",
649 dir
,strerror(errno
));
653 strlcpy(fname
,dir
,MAXPATHLEN
);
655 if (fname
[l
-1] != '/') {
656 if (l
== MAXPATHLEN
-1) {
658 rprintf(FERROR
,"skipping long-named directory %s\n",fname
);
662 strlcat(fname
,"/", MAXPATHLEN
);
665 p
= fname
+ strlen(fname
);
667 local_exclude_list
= NULL
;
670 if (strlen(fname
) + strlen(".cvsignore") <= MAXPATHLEN
-1) {
671 strcpy(p
,".cvsignore");
672 local_exclude_list
= make_exclude_list(fname
,NULL
,0,0);
675 rprintf(FINFO
,"cannot cvs-exclude in long-named directory %s\n",fname
);
679 for (di
=readdir(d
); di
; di
=readdir(d
)) {
680 char *dname
= d_name(di
);
681 if (strcmp(dname
,".")==0 ||
682 strcmp(dname
,"..")==0)
684 strlcpy(p
,dname
,MAXPATHLEN
-l
);
685 send_file_name(f
,flist
,fname
,recurse
,0);
688 if (local_exclude_list
) {
689 add_exclude_list("!", &local_exclude_list
, 0);
696 struct file_list
*send_file_list(int f
,int argc
,char *argv
[])
700 char *p
,*dir
,*olddir
;
701 char lastpath
[MAXPATHLEN
]="";
702 struct file_list
*flist
;
705 if (verbose
&& recurse
&& !am_server
&& f
!= -1) {
706 rprintf(FINFO
,"building file list ... ");
708 rprintf(FINFO
, "\n");
712 start_write
= stats
.total_written
;
717 io_start_buffering(f
);
720 for (i
=0;i
<argc
;i
++) {
721 char *fname
= topsrcname
;
723 strlcpy(fname
,argv
[i
],MAXPATHLEN
);
726 if (l
!= 1 && fname
[l
-1] == '/') {
727 if ((l
== 2) && (fname
[0] == '.')) {
728 /* Turn ./ into just . rather than ./.
729 This was put in to avoid a problem with
730 rsync -aR --delete from ./
731 The send_file_name() below of ./ was
732 mysteriously preventing deletes */
735 strlcat(fname
,".",MAXPATHLEN
);
739 if (link_stat(fname
,&st
) != 0) {
742 rprintf(FERROR
,"link_stat %s : %s\n",fname
,strerror(errno
));
747 if (S_ISDIR(st
.st_mode
) && !recurse
) {
748 rprintf(FINFO
,"skipping directory %s\n",fname
);
755 if (!relative_paths
) {
756 p
= strrchr(fname
,'/');
765 } else if (f
!= -1 && (p
=strrchr(fname
,'/'))) {
766 /* this ensures we send the intermediate directories,
767 thus getting their permissions right */
769 if (strcmp(lastpath
,fname
)) {
770 strlcpy(lastpath
, fname
, sizeof(lastpath
));
772 for (p
=fname
+1; (p
=strchr(p
,'/')); p
++) {
773 int copy_links_saved
= copy_links
;
774 int recurse_saved
= recurse
;
776 copy_links
= copy_unsafe_links
;
777 /* set recurse to 1 to prevent make_file
778 from ignoring directory, but still
779 turn off the recursive parameter to
782 send_file_name(f
, flist
, fname
, 0, 0);
783 copy_links
= copy_links_saved
;
784 recurse
= recurse_saved
;
796 olddir
= push_dir(dir
, 1);
800 rprintf(FERROR
,"push_dir %s : %s\n",
801 dir
,strerror(errno
));
809 set_filesystem(fname
);
811 send_file_name(f
,flist
,fname
,recurse
,FLAG_DELETE
);
813 if (olddir
!= NULL
) {
815 if (pop_dir(olddir
) != 0) {
816 rprintf(FERROR
,"pop_dir %s : %s\n",
817 dir
,strerror(errno
));
818 exit_cleanup(RERR_FILESELECT
);
823 topsrcname
[0] = '\0';
826 send_file_entry(NULL
,f
,0);
829 if (verbose
&& recurse
&& !am_server
&& f
!= -1)
830 rprintf(FINFO
,"done\n");
832 clean_flist(flist
, 0);
834 /* now send the uid/gid list. This was introduced in protocol
836 if (f
!= -1 && remote_version
>= 15) {
840 /* if protocol version is >= 17 then send the io_error flag */
841 if (f
!= -1 && remote_version
>= 17) {
842 extern int module_id
;
843 write_int(f
, lp_ignore_errors(module_id
)? 0 : io_error
);
848 stats
.flist_size
= stats
.total_written
- start_write
;
849 stats
.num_files
= flist
->count
;
850 if (write_batch
) /* dw */
851 write_batch_flist_info(flist
->count
, flist
->files
);
855 rprintf(FINFO
,"send_file_list done\n");
861 struct file_list
*recv_file_list(int f
)
863 struct file_list
*flist
;
866 extern int list_only
;
868 if (verbose
&& recurse
&& !am_server
) {
869 rprintf(FINFO
,"receiving file list ... ");
873 start_read
= stats
.total_read
;
875 flist
= (struct file_list
*)malloc(sizeof(flist
[0]));
880 flist
->malloced
=1000;
881 flist
->files
= (struct file_struct
**)malloc(sizeof(flist
->files
[0])*
887 for (flags
=read_byte(f
); flags
; flags
=read_byte(f
)) {
888 int i
= flist
->count
;
890 if (i
>= flist
->malloced
) {
891 if (flist
->malloced
< 1000)
892 flist
->malloced
+= 1000;
894 flist
->malloced
*= 2;
895 flist
->files
=(struct file_struct
**)realloc(flist
->files
,
896 sizeof(flist
->files
[0])*
902 receive_file_entry(&flist
->files
[i
],flags
,f
);
904 if (S_ISREG(flist
->files
[i
]->mode
))
905 stats
.total_size
+= flist
->files
[i
]->length
;
910 rprintf(FINFO
,"recv_file_name(%s)\n",f_name(flist
->files
[i
]));
915 rprintf(FINFO
,"received %d names\n",flist
->count
);
917 clean_flist(flist
, relative_paths
);
919 if (verbose
&& recurse
&& !am_server
) {
920 rprintf(FINFO
,"done\n");
923 /* now recv the uid/gid list. This was introduced in protocol version 15 */
924 if (f
!= -1 && remote_version
>= 15) {
925 recv_uid_list(f
, flist
);
928 /* if protocol version is >= 17 then recv the io_error flag */
929 if (f
!= -1 && remote_version
>= 17 && !read_batch
) { /* dw-added readbatch */
930 extern int module_id
;
931 extern int ignore_errors
;
932 if (lp_ignore_errors(module_id
) || ignore_errors
) {
935 io_error
|= read_int(f
);
941 for (i
=0;i
<flist
->count
;i
++) {
942 list_file_entry(flist
->files
[i
]);
948 rprintf(FINFO
,"recv_file_list done\n");
950 stats
.flist_size
= stats
.total_read
- start_read
;
951 stats
.num_files
= flist
->count
;
956 out_of_memory("recv_file_list");
957 return NULL
; /* not reached */
961 int file_compare(struct file_struct
**f1
,struct file_struct
**f2
)
963 if (!(*f1
)->basename
&& !(*f2
)->basename
) return 0;
964 if (!(*f1
)->basename
) return -1;
965 if (!(*f2
)->basename
) return 1;
966 if ((*f1
)->dirname
== (*f2
)->dirname
)
967 return u_strcmp((*f1
)->basename
, (*f2
)->basename
);
968 return u_strcmp(f_name(*f1
),f_name(*f2
));
972 int flist_find(struct file_list
*flist
,struct file_struct
*f
)
974 int low
=0,high
=flist
->count
-1;
976 if (flist
->count
<= 0) return -1;
978 while (low
!= high
) {
979 int mid
= (low
+high
)/2;
980 int ret
= file_compare(&flist
->files
[flist_up(flist
, mid
)],&f
);
981 if (ret
== 0) return flist_up(flist
, mid
);
989 if (file_compare(&flist
->files
[flist_up(flist
,low
)],&f
) == 0)
990 return flist_up(flist
,low
);
998 void free_file(struct file_struct
*file
)
1001 if (file
->basename
) free(file
->basename
);
1002 if (file
->link
) free(file
->link
);
1003 if (file
->sum
) free(file
->sum
);
1009 * allocate a new file list
1011 struct file_list
*flist_new()
1013 struct file_list
*flist
;
1015 flist
= (struct file_list
*)malloc(sizeof(flist
[0]));
1016 if (!flist
) out_of_memory("send_file_list");
1019 flist
->malloced
= 1000;
1020 flist
->files
= (struct file_struct
**)malloc(sizeof(flist
->files
[0])*
1022 if (!flist
->files
) out_of_memory("send_file_list");
1024 flist
->string_area
= string_area_new(0);
1026 flist
->string_area
= NULL
;
1031 * free up all elements in a flist
1033 void flist_free(struct file_list
*flist
)
1036 for (i
=1;i
<flist
->count
;i
++) {
1037 if (!flist
->string_area
)
1038 free_file(flist
->files
[i
]);
1039 free(flist
->files
[i
]);
1041 memset((char *)flist
->files
, 0, sizeof(flist
->files
[0])*flist
->count
);
1043 if (flist
->string_area
)
1044 string_area_free(flist
->string_area
);
1045 memset((char *)flist
, 0, sizeof(*flist
));
1051 * This routine ensures we don't have any duplicate names in our file list.
1052 * duplicate names can cause corruption because of the pipelining
1054 static void clean_flist(struct file_list
*flist
, int strip_root
)
1058 if (!flist
|| flist
->count
== 0)
1061 qsort(flist
->files
,flist
->count
,
1062 sizeof(flist
->files
[0]),
1063 (int (*)())file_compare
);
1065 for (i
=1;i
<flist
->count
;i
++) {
1066 if (flist
->files
[i
]->basename
&&
1067 flist
->files
[i
-1]->basename
&&
1068 strcmp(f_name(flist
->files
[i
]),
1069 f_name(flist
->files
[i
-1])) == 0) {
1070 if (verbose
> 1 && !am_server
)
1071 rprintf(FINFO
,"removing duplicate name %s from file list %d\n",
1072 f_name(flist
->files
[i
-1]),i
-1);
1073 /* it's not great that the flist knows the semantics of the
1074 * file memory usage, but i'd rather not add a flag byte
1075 * to that struct. XXX can i use a bit in the flags field? */
1076 if (flist
->string_area
)
1077 flist
->files
[i
][0] = null_file
;
1079 free_file(flist
->files
[i
]);
1084 /* we need to strip off the root directory in the case
1085 of relative paths, but this must be done _after_
1086 the sorting phase */
1087 for (i
=0;i
<flist
->count
;i
++) {
1088 if (flist
->files
[i
]->dirname
&&
1089 flist
->files
[i
]->dirname
[0] == '/') {
1090 memmove(&flist
->files
[i
]->dirname
[0],
1091 &flist
->files
[i
]->dirname
[1],
1092 strlen(flist
->files
[i
]->dirname
));
1095 if (flist
->files
[i
]->dirname
&&
1096 !flist
->files
[i
]->dirname
[0]) {
1097 flist
->files
[i
]->dirname
= NULL
;
1103 if (verbose
<= 3) return;
1105 for (i
=0;i
<flist
->count
;i
++) {
1106 rprintf(FINFO
,"[%d] i=%d %s %s mode=0%o len=%.0f\n",
1108 NS(flist
->files
[i
]->dirname
),
1109 NS(flist
->files
[i
]->basename
),
1110 (int) flist
->files
[i
]->mode
,
1111 (double)flist
->files
[i
]->length
);
1117 * return the full filename of a flist entry
1119 char *f_name(struct file_struct
*f
)
1121 static char names
[10][MAXPATHLEN
];
1125 if (!f
|| !f
->basename
) return NULL
;
1130 strlcpy(p
, f
->dirname
, MAXPATHLEN
);
1131 strlcat(p
, "/", MAXPATHLEN
);
1132 strlcat(p
, f
->basename
, MAXPATHLEN
);
1134 strlcpy(p
, f
->basename
, MAXPATHLEN
);