Fix a bug with rsync -R --delete from ./ as reported in PR#1532
[rsync/rsync.git] / flist.c
1 /* 
2    Copyright (C) Andrew Tridgell 1996
3    Copyright (C) Paul Mackerras 1996
4    
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.
9    
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.
14    
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.
18 */
19
20 /* generate and receive file lists */
21
22 #include "rsync.h"
23
24 extern struct stats stats;
25
26 extern int csum_length;
27
28 extern int verbose;
29 extern int am_server;
30 extern int always_checksum;
31
32 extern int cvs_exclude;
33
34 extern int recurse;
35
36 extern int one_file_system;
37 extern int make_backups;
38 extern int preserve_links;
39 extern int preserve_hard_links;
40 extern int preserve_perms;
41 extern int preserve_devices;
42 extern int preserve_uid;
43 extern int preserve_gid;
44 extern int preserve_times;
45 extern int relative_paths;
46 extern int copy_links;
47 extern int copy_unsafe_links;
48 extern int remote_version;
49 extern int io_error;
50
51 static char topsrcname[MAXPATHLEN];
52
53 static struct exclude_struct **local_exclude_list;
54
55 static void clean_flist(struct file_list *flist, int strip_root);
56
57
58 static void list_file_entry(struct file_struct *f)
59 {
60         char perms[11] = "----------";
61         char *perm_map = "rwxrwxrwx";
62         int i;
63
64         if (!f->basename)
65                 /* this can happen if duplicate names were removed */
66                 return;
67
68         for (i=0;i<9;i++) {
69                 if (f->mode & (1<<i)) perms[9-i] = perm_map[8-i];
70         }
71         if (S_ISLNK(f->mode)) perms[0] = 'l';
72         if (S_ISDIR(f->mode)) perms[0] = 'd';
73         if (S_ISBLK(f->mode)) perms[0] = 'b';
74         if (S_ISCHR(f->mode)) perms[0] = 'c';
75         if (S_ISSOCK(f->mode)) perms[0] = 's';
76         if (S_ISFIFO(f->mode)) perms[0] = 'p';
77         
78         if (preserve_links && S_ISLNK(f->mode)) {
79                 rprintf(FINFO,"%s %11.0f %s %s -> %s\n", 
80                         perms, 
81                         (double)f->length, timestring(f->modtime), 
82                         f_name(f), f->link);
83         } else {
84                 rprintf(FINFO,"%s %11.0f %s %s\n", 
85                         perms, 
86                         (double)f->length, timestring(f->modtime), f_name(f));
87         }
88 }
89
90
91 int readlink_stat(const char *Path, STRUCT_STAT *Buffer, char *Linkbuf) 
92 {
93 #if SUPPORT_LINKS
94         if (copy_links) {
95                 return do_stat(Path, Buffer);
96         }
97         if (do_lstat(Path, Buffer) == -1) {
98                 return -1;
99         }
100         if (S_ISLNK(Buffer->st_mode)) {
101                 int l;
102                 if ((l = readlink(Path,Linkbuf,MAXPATHLEN-1)) == -1) {
103                         return -1;
104                 }
105                 Linkbuf[l] = 0;
106                 if (copy_unsafe_links && (topsrcname[0] != '\0') &&
107                                     unsafe_symlink(Linkbuf, topsrcname)) {
108                         return do_stat(Path, Buffer);
109                 }
110         }
111         return 0;
112 #else
113         return do_stat(Path, Buffer);
114 #endif
115 }
116
117 int link_stat(const char *Path, STRUCT_STAT *Buffer) 
118 {
119 #if SUPPORT_LINKS
120     if (copy_links) {
121         return do_stat(Path, Buffer);
122     } else {
123         return do_lstat(Path, Buffer);
124     }
125 #else
126     return do_stat(Path, Buffer);
127 #endif
128 }
129
130 /*
131   This function is used to check if a file should be included/excluded
132   from the list of files based on its name and type etc
133  */
134 static int match_file_name(char *fname,STRUCT_STAT *st)
135 {
136   if (check_exclude(fname,local_exclude_list,st)) {
137     if (verbose > 2)
138       rprintf(FINFO,"excluding file %s\n",fname);
139     return 0;
140   }
141   return 1;
142 }
143
144 /* used by the one_file_system code */
145 static dev_t filesystem_dev;
146
147 static void set_filesystem(char *fname)
148 {
149   STRUCT_STAT st;
150   if (link_stat(fname,&st) != 0) return;
151   filesystem_dev = st.st_dev;
152 }
153
154
155 static int to_wire_mode(mode_t mode)
156 {
157         if (S_ISLNK(mode) && (S_IFLNK != 0120000)) {
158                 return (mode & ~(_S_IFMT)) | 0120000;
159         }
160         return (int)mode;
161 }
162
163 static mode_t from_wire_mode(int mode)
164 {
165         if ((mode & (_S_IFMT)) == 0120000 && (S_IFLNK != 0120000)) {
166                 return (mode & ~(_S_IFMT)) | S_IFLNK;
167         }
168         return (mode_t)mode;
169 }
170
171
172 static void send_directory(int f,struct file_list *flist,char *dir);
173
174 static char *flist_dir;
175
176
177 static void send_file_entry(struct file_struct *file,int f,unsigned base_flags)
178 {
179         unsigned char flags;
180         static time_t last_time;
181         static mode_t last_mode;
182         static dev_t last_rdev;
183         static uid_t last_uid;
184         static gid_t last_gid;
185         static char lastname[MAXPATHLEN];
186         char *fname;
187         int l1,l2;
188
189         if (f == -1) return;
190
191         if (!file) {
192                 write_byte(f,0);
193                 return;
194         }
195
196         fname = f_name(file);
197
198         flags = base_flags;
199
200         if (file->mode == last_mode) flags |= SAME_MODE;
201         if (file->rdev == last_rdev) flags |= SAME_RDEV;
202         if (file->uid == last_uid) flags |= SAME_UID;
203         if (file->gid == last_gid) flags |= SAME_GID;
204         if (file->modtime == last_time) flags |= SAME_TIME;
205
206         for (l1=0;lastname[l1] && (fname[l1] == lastname[l1]) && (l1 < 255);l1++) ;  
207         l2 = strlen(fname) - l1;
208
209         if (l1 > 0) flags |= SAME_NAME;
210         if (l2 > 255) flags |= LONG_NAME;
211
212         /* we must make sure we don't send a zero flags byte or the other
213            end will terminate the flist transfer */
214         if (flags == 0 && !S_ISDIR(file->mode)) flags |= FLAG_DELETE;
215         if (flags == 0) flags |= LONG_NAME;
216
217         write_byte(f,flags);  
218         if (flags & SAME_NAME)
219                 write_byte(f,l1);
220         if (flags & LONG_NAME)
221                 write_int(f,l2);
222         else
223                 write_byte(f,l2);
224         write_buf(f,fname+l1,l2);
225
226         write_longint(f,file->length);
227         if (!(flags & SAME_TIME))
228                 write_int(f,(int)file->modtime);
229         if (!(flags & SAME_MODE))
230                 write_int(f,to_wire_mode(file->mode));
231         if (preserve_uid && !(flags & SAME_UID)) {
232                 add_uid(file->uid);
233                 write_int(f,(int)file->uid);
234         }
235         if (preserve_gid && !(flags & SAME_GID)) {
236                 add_gid(file->gid);
237                 write_int(f,(int)file->gid);
238         }
239         if (preserve_devices && IS_DEVICE(file->mode) && !(flags & SAME_RDEV))
240                 write_int(f,(int)file->rdev);
241
242 #if SUPPORT_LINKS
243         if (preserve_links && S_ISLNK(file->mode)) {
244                 write_int(f,strlen(file->link));
245                 write_buf(f,file->link,strlen(file->link));
246         }
247 #endif
248
249 #if SUPPORT_HARD_LINKS
250         if (preserve_hard_links && S_ISREG(file->mode)) {
251                 write_int(f,(int)file->dev);
252                 write_int(f,(int)file->inode);
253         }
254 #endif
255
256         if (always_checksum) {
257                 write_buf(f,file->sum,csum_length);
258         }       
259
260         last_mode = file->mode;
261         last_rdev = file->rdev;
262         last_uid = file->uid;
263         last_gid = file->gid;
264         last_time = file->modtime;
265
266         strlcpy(lastname,fname,MAXPATHLEN);
267         lastname[MAXPATHLEN-1] = 0;
268 }
269
270
271
272 static void receive_file_entry(struct file_struct **fptr,
273                                unsigned flags,int f)
274 {
275         static time_t last_time;
276         static mode_t last_mode;
277         static dev_t last_rdev;
278         static uid_t last_uid;
279         static gid_t last_gid;
280         static char lastname[MAXPATHLEN];
281         char thisname[MAXPATHLEN];
282         int l1=0,l2=0;
283         char *p;
284         struct file_struct *file;
285
286         if (flags & SAME_NAME)
287                 l1 = read_byte(f);
288   
289         if (flags & LONG_NAME)
290                 l2 = read_int(f);
291         else
292                 l2 = read_byte(f);
293
294         file = (struct file_struct *)malloc(sizeof(*file));
295         if (!file) out_of_memory("receive_file_entry");
296         memset((char *)file, 0, sizeof(*file));
297         (*fptr) = file;
298
299         if (l2 >= MAXPATHLEN-l1) overflow("receive_file_entry");
300
301         strlcpy(thisname,lastname,l1+1);
302         read_sbuf(f,&thisname[l1],l2);
303         thisname[l1+l2] = 0;
304
305         strlcpy(lastname,thisname,MAXPATHLEN);
306         lastname[MAXPATHLEN-1] = 0;
307
308         clean_fname(thisname);
309
310         if ((p = strrchr(thisname,'/'))) {
311                 static char *lastdir;
312                 *p = 0;
313                 if (lastdir && strcmp(thisname, lastdir)==0) {
314                         file->dirname = lastdir;
315                 } else {
316                         file->dirname = strdup(thisname);
317                         lastdir = file->dirname;
318                 }
319                 file->basename = strdup(p+1);
320         } else {
321                 file->dirname = NULL;
322                 file->basename = strdup(thisname);
323         }
324
325         if (!file->basename) out_of_memory("receive_file_entry 1");
326
327
328         file->flags = flags;
329         file->length = read_longint(f);
330         file->modtime = (flags & SAME_TIME) ? last_time : (time_t)read_int(f);
331         file->mode = (flags & SAME_MODE) ? last_mode : from_wire_mode(read_int(f));
332         if (preserve_uid)
333                 file->uid = (flags & SAME_UID) ? last_uid : (uid_t)read_int(f);
334         if (preserve_gid)
335                 file->gid = (flags & SAME_GID) ? last_gid : (gid_t)read_int(f);
336         if (preserve_devices && IS_DEVICE(file->mode))
337                 file->rdev = (flags & SAME_RDEV) ? last_rdev : (dev_t)read_int(f);
338
339         if (preserve_links && S_ISLNK(file->mode)) {
340                 int l = read_int(f);
341                 file->link = (char *)malloc(l+1);
342                 if (!file->link) out_of_memory("receive_file_entry 2");
343                 read_sbuf(f,file->link,l);
344         }
345
346 #if SUPPORT_HARD_LINKS
347         if (preserve_hard_links && S_ISREG(file->mode)) {
348                 file->dev = read_int(f);
349                 file->inode = read_int(f);
350         }
351 #endif
352   
353         if (always_checksum) {
354                 file->sum = (char *)malloc(MD4_SUM_LENGTH);
355                 if (!file->sum) out_of_memory("md4 sum");
356                 read_buf(f,file->sum,csum_length);
357         }
358   
359         last_mode = file->mode;
360         last_rdev = file->rdev;
361         last_uid = file->uid;
362         last_gid = file->gid;
363         last_time = file->modtime;
364
365         if (!preserve_perms) {
366                 extern int orig_umask;
367                 /* set an appropriate set of permissions based on original
368                    permissions and umask. This emulates what GNU cp does */
369                 file->mode &= ~orig_umask;
370         }
371 }
372
373
374 /* determine if a file in a different filesstem should be skipped
375    when one_file_system is set. We bascally only want to include
376    the mount points - but they can be hard to find! */
377 static int skip_filesystem(char *fname, STRUCT_STAT *st)
378 {
379         STRUCT_STAT st2;
380         char *p = strrchr(fname, '/');
381
382         /* skip all but directories */
383         if (!S_ISDIR(st->st_mode)) return 1;
384
385         /* if its not a subdirectory then allow */
386         if (!p) return 0;
387
388         *p = 0;
389         if (link_stat(fname, &st2)) {
390                 *p = '/';
391                 return 0;
392         }
393         *p = '/';
394         
395         return (st2.st_dev != filesystem_dev);
396 }
397
398 static struct file_struct *make_file(int f, char *fname)
399 {
400         struct file_struct *file;
401         STRUCT_STAT st;
402         char sum[SUM_LENGTH];
403         char *p;
404         char cleaned_name[MAXPATHLEN];
405         char linkbuf[MAXPATHLEN];
406         extern int delete_excluded;
407
408         strlcpy(cleaned_name, fname, MAXPATHLEN);
409         cleaned_name[MAXPATHLEN-1] = 0;
410         clean_fname(cleaned_name);
411         fname = cleaned_name;
412
413         memset(sum,0,SUM_LENGTH);
414
415         if (readlink_stat(fname,&st,linkbuf) != 0) {
416                 io_error = 1;
417                 rprintf(FERROR,"%s: %s\n",
418                         fname,strerror(errno));
419                 return NULL;
420         }
421
422         if (S_ISDIR(st.st_mode) && !recurse) {
423                 rprintf(FINFO,"skipping directory %s\n",fname);
424                 return NULL;
425         }
426         
427         if (one_file_system && st.st_dev != filesystem_dev) {
428                 if (skip_filesystem(fname, &st))
429                         return NULL;
430         }
431         
432         /* f is set to -1 when calculating deletion file list */
433         if (((f != -1) || !delete_excluded) && !match_file_name(fname,&st))
434                 return NULL;
435         
436         if (verbose > 2)
437                 rprintf(FINFO,"make_file(%d,%s)\n",f,fname);
438         
439         file = (struct file_struct *)malloc(sizeof(*file));
440         if (!file) out_of_memory("make_file");
441         memset((char *)file,0,sizeof(*file));
442
443         if ((p = strrchr(fname,'/'))) {
444                 static char *lastdir;
445                 *p = 0;
446                 if (lastdir && strcmp(fname, lastdir)==0) {
447                         file->dirname = lastdir;
448                 } else {
449                         file->dirname = strdup(fname);
450                         lastdir = file->dirname;
451                 }
452                 file->basename = strdup(p+1);
453                 *p = '/';
454         } else {
455                 file->dirname = NULL;
456                 file->basename = strdup(fname);
457         }
458
459         file->modtime = st.st_mtime;
460         file->length = st.st_size;
461         file->mode = st.st_mode;
462         file->uid = st.st_uid;
463         file->gid = st.st_gid;
464         file->dev = st.st_dev;
465         file->inode = st.st_ino;
466 #ifdef HAVE_ST_RDEV
467         file->rdev = st.st_rdev;
468 #endif
469
470 #if SUPPORT_LINKS
471         if (S_ISLNK(st.st_mode)) {
472                 file->link = strdup(linkbuf);
473         }
474 #endif
475
476         if (always_checksum) {
477                 file->sum = (char *)malloc(MD4_SUM_LENGTH);
478                 if (!file->sum) out_of_memory("md4 sum");
479                 /* drat. we have to provide a null checksum for non-regular
480                    files in order to be compatible with earlier versions
481                    of rsync */
482                 if (S_ISREG(st.st_mode)) {
483                         file_checksum(fname,file->sum,st.st_size);
484                 } else {
485                         memset(file->sum, 0, MD4_SUM_LENGTH);
486                 }
487         }       
488
489         if (flist_dir) {
490                 static char *lastdir;
491                 if (lastdir && strcmp(lastdir, flist_dir)==0) {
492                         file->basedir = lastdir;
493                 } else {
494                         file->basedir = strdup(flist_dir);
495                         lastdir = file->basedir;
496                 }
497         } else {
498                 file->basedir = NULL;
499         }
500
501         if (!S_ISDIR(st.st_mode))
502                 stats.total_size += st.st_size;
503
504         return file;
505 }
506
507
508
509 void send_file_name(int f,struct file_list *flist,char *fname,
510                            int recursive, unsigned base_flags)
511 {
512   struct file_struct *file;
513
514   file = make_file(f,fname);
515
516   if (!file) return;  
517   
518   if (flist->count >= flist->malloced) {
519           if (flist->malloced < 1000)
520                   flist->malloced += 1000;
521           else
522                   flist->malloced *= 2;
523           flist->files = (struct file_struct **)realloc(flist->files,
524                                                         sizeof(flist->files[0])*
525                                                         flist->malloced);
526           if (!flist->files)
527                   out_of_memory("send_file_name");
528   }
529
530   if (strcmp(file->basename,"")) {
531     flist->files[flist->count++] = file;
532     send_file_entry(file,f,base_flags);
533   }
534
535   if (S_ISDIR(file->mode) && recursive) {
536           struct exclude_struct **last_exclude_list = local_exclude_list;
537           send_directory(f,flist,f_name(file));
538           local_exclude_list = last_exclude_list;
539           return;
540   }
541 }
542
543
544
545 static void send_directory(int f,struct file_list *flist,char *dir)
546 {
547         DIR *d;
548         struct dirent *di;
549         char fname[MAXPATHLEN];
550         int l;
551         char *p;
552
553         d = opendir(dir);
554         if (!d) {
555                 io_error = 1;
556                 rprintf(FERROR,"opendir(%s): %s\n",
557                         dir,strerror(errno));
558                 return;
559         }
560
561         strlcpy(fname,dir,MAXPATHLEN);
562         l = strlen(fname);
563         if (fname[l-1] != '/') {
564                 if (l == MAXPATHLEN-1) {
565                         io_error = 1;
566                         rprintf(FERROR,"skipping long-named directory %s\n",fname);
567                         closedir(d);
568                         return;
569                 }
570                 strlcat(fname,"/", MAXPATHLEN);
571                 l++;
572         }
573         p = fname + strlen(fname);
574
575         local_exclude_list = NULL;
576
577         if (cvs_exclude) {
578                 if (strlen(fname) + strlen(".cvsignore") <= MAXPATHLEN-1) {
579                         strcpy(p,".cvsignore");
580                         local_exclude_list = make_exclude_list(fname,NULL,0,0);
581                 } else {
582                         io_error = 1;
583                         rprintf(FINFO,"cannot cvs-exclude in long-named directory %s\n",fname);
584                 }
585         }  
586         
587         for (di=readdir(d); di; di=readdir(d)) {
588                 char *dname = d_name(di);
589                 if (strcmp(dname,".")==0 ||
590                     strcmp(dname,"..")==0)
591                         continue;
592                 strlcpy(p,dname,MAXPATHLEN-l);
593                 send_file_name(f,flist,fname,recurse,0);
594         }
595
596         if (local_exclude_list) {
597                 add_exclude_list("!", &local_exclude_list, 0);
598         }
599
600         closedir(d);
601 }
602
603
604
605 struct file_list *send_file_list(int f,int argc,char *argv[])
606 {
607         int i,l;
608         STRUCT_STAT st;
609         char *p,*dir,*olddir;
610         char lastpath[MAXPATHLEN]="";
611         struct file_list *flist;
612         int64 start_write;
613
614         if (verbose && recurse && !am_server && f != -1) {
615                 rprintf(FINFO,"building file list ... ");
616                 rflush(FINFO);
617         }
618
619         start_write = stats.total_written;
620
621         flist = (struct file_list *)malloc(sizeof(flist[0]));
622         if (!flist) out_of_memory("send_file_list");
623
624         flist->count=0;
625         flist->malloced = 1000;
626         flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
627                                                      flist->malloced);
628         if (!flist->files) out_of_memory("send_file_list");
629
630         if (f != -1) {
631                 io_start_buffering(f);
632         }
633
634         for (i=0;i<argc;i++) {
635                 char *fname = topsrcname;
636
637                 strlcpy(fname,argv[i],MAXPATHLEN);
638
639                 l = strlen(fname);
640                 if (l != 1 && fname[l-1] == '/') {
641                         if ((l == 2) && (fname[0] == '.')) {
642                                 /*  Turn ./ into just . rather than ./.
643                                     This was put in to avoid a problem with
644                                       rsync -aR --delete from ./
645                                     The send_file_name() below of ./ was
646                                     mysteriously preventing deletes */
647                                 fname[1] = 0;
648                         } else {
649                                 strlcat(fname,".",MAXPATHLEN);
650                         }
651                 }
652
653                 if (link_stat(fname,&st) != 0) {
654                         io_error=1;
655                         rprintf(FERROR,"%s : %s\n",fname,strerror(errno));
656                         continue;
657                 }
658
659                 if (S_ISDIR(st.st_mode) && !recurse) {
660                         rprintf(FINFO,"skipping directory %s\n",fname);
661                         continue;
662                 }
663
664                 dir = NULL;
665                 olddir = NULL;
666
667                 if (!relative_paths) {
668                         p = strrchr(fname,'/');
669                         if (p) {
670                                 *p = 0;
671                                 if (p == fname) 
672                                         dir = "/";
673                                 else
674                                         dir = fname;      
675                                 fname = p+1;      
676                         }
677                 } else if (f != -1 && (p=strrchr(fname,'/'))) {
678                         /* this ensures we send the intermediate directories,
679                            thus getting their permissions right */
680                         *p = 0;
681                         if (strcmp(lastpath,fname)) {
682                                 strlcpy(lastpath, fname, sizeof(lastpath));
683                                 *p = '/';
684                                 for (p=fname+1; (p=strchr(p,'/')); p++) {
685                                         int copy_links_saved = copy_links;
686                                         *p = 0;
687                                         copy_links = copy_unsafe_links;
688                                         send_file_name(f, flist, fname, 0, 0);
689                                         copy_links = copy_links_saved;
690                                         *p = '/';
691                                 }
692                         } else {
693                                 *p = '/';
694                         }
695                 }
696                 
697                 if (!*fname)
698                         fname = ".";
699                 
700                 if (dir && *dir) {
701                         olddir = push_dir(dir, 1);
702
703                         if (!olddir) {
704                                 io_error=1;
705                                 rprintf(FERROR,"push_dir %s : %s\n",
706                                         dir,strerror(errno));
707                                 continue;
708                         }
709
710                         flist_dir = dir;
711                 }
712                 
713                 if (one_file_system)
714                         set_filesystem(fname);
715
716                 if (!recurse || !send_included_file_names(f,flist))
717                         send_file_name(f,flist,fname,recurse,FLAG_DELETE);
718
719                 if (olddir != NULL) {
720                         flist_dir = NULL;
721                         if (pop_dir(olddir) != 0) {
722                                 rprintf(FERROR,"pop_dir %s : %s\n",
723                                         dir,strerror(errno));
724                                 exit_cleanup(RERR_FILESELECT);
725                         }
726                 }
727         }
728
729         topsrcname[0] = '\0';
730
731         if (f != -1) {
732                 send_file_entry(NULL,f,0);
733         }
734
735         if (verbose && recurse && !am_server && f != -1)
736                 rprintf(FINFO,"done\n");
737         
738         clean_flist(flist, 0);
739         
740         /* now send the uid/gid list. This was introduced in protocol
741            version 15 */
742         if (f != -1 && remote_version >= 15) {
743                 send_uid_list(f);
744         }
745
746         /* if protocol version is >= 17 then send the io_error flag */
747         if (f != -1 && remote_version >= 17) {
748                 write_int(f, io_error);
749         }
750
751         if (f != -1) {
752                 io_end_buffering(f);
753                 stats.flist_size = stats.total_written - start_write;
754                 stats.num_files = flist->count;
755         }
756
757         if (verbose > 2)
758                 rprintf(FINFO,"send_file_list done\n");
759
760         return flist;
761 }
762
763
764 struct file_list *recv_file_list(int f)
765 {
766   struct file_list *flist;
767   unsigned char flags;
768   int64 start_read;
769   extern int list_only;
770
771   if (verbose && recurse && !am_server) {
772     rprintf(FINFO,"receiving file list ... ");
773     rflush(FINFO);
774   }
775
776   start_read = stats.total_read;
777
778   flist = (struct file_list *)malloc(sizeof(flist[0]));
779   if (!flist)
780     goto oom;
781
782   flist->count=0;
783   flist->malloced=1000;
784   flist->files = (struct file_struct **)malloc(sizeof(flist->files[0])*
785                                                flist->malloced);
786   if (!flist->files)
787     goto oom;
788
789
790   for (flags=read_byte(f); flags; flags=read_byte(f)) {
791     int i = flist->count;
792
793     if (i >= flist->malloced) {
794           if (flist->malloced < 1000)
795                   flist->malloced += 1000;
796           else
797                   flist->malloced *= 2;
798           flist->files =(struct file_struct **)realloc(flist->files,
799                                                        sizeof(flist->files[0])*
800                                                        flist->malloced);
801           if (!flist->files)
802                   goto oom;
803     }
804
805     receive_file_entry(&flist->files[i],flags,f);
806
807     if (S_ISREG(flist->files[i]->mode))
808             stats.total_size += flist->files[i]->length;
809
810     flist->count++;
811
812     if (verbose > 2)
813       rprintf(FINFO,"recv_file_name(%s)\n",f_name(flist->files[i]));
814   }
815
816
817   if (verbose > 2)
818     rprintf(FINFO,"received %d names\n",flist->count);
819
820   clean_flist(flist, relative_paths);
821
822   if (verbose && recurse && !am_server) {
823     rprintf(FINFO,"done\n");
824   }
825
826   /* now recv the uid/gid list. This was introduced in protocol version 15 */
827   if (f != -1 && remote_version >= 15) {
828           recv_uid_list(f, flist);
829   }
830
831   /* if protocol version is >= 17 then recv the io_error flag */
832   if (f != -1 && remote_version >= 17) {
833           io_error |= read_int(f);
834   }
835
836   if (list_only) {
837           int i;
838           for (i=0;i<flist->count;i++) {
839                   list_file_entry(flist->files[i]);
840           }
841   }
842
843
844   if (verbose > 2)
845     rprintf(FINFO,"recv_file_list done\n");
846
847   stats.flist_size = stats.total_read - start_read;
848   stats.num_files = flist->count;
849
850   return flist;
851
852 oom:
853     out_of_memory("recv_file_list");
854     return NULL; /* not reached */
855 }
856
857
858 int file_compare(struct file_struct **f1,struct file_struct **f2)
859 {
860         if (!(*f1)->basename && !(*f2)->basename) return 0;
861         if (!(*f1)->basename) return -1;
862         if (!(*f2)->basename) return 1;
863         if ((*f1)->dirname == (*f2)->dirname)
864                 return u_strcmp((*f1)->basename, (*f2)->basename);
865         return u_strcmp(f_name(*f1),f_name(*f2));
866 }
867
868
869 int flist_find(struct file_list *flist,struct file_struct *f)
870 {
871         int low=0,high=flist->count-1;
872
873         if (flist->count <= 0) return -1;
874
875         while (low != high) {
876                 int mid = (low+high)/2;
877                 int ret = file_compare(&flist->files[flist_up(flist, mid)],&f);
878                 if (ret == 0) return flist_up(flist, mid);
879                 if (ret > 0) {
880                         high=mid;
881                 } else {
882                         low=mid+1;
883                 }
884         }
885
886         if (file_compare(&flist->files[flist_up(flist,low)],&f) == 0)
887                 return flist_up(flist,low);
888         return -1;
889 }
890
891
892 /*
893  * free up one file
894  */
895 static void free_file(struct file_struct *file)
896 {
897         if (!file) return;
898         if (file->basename) free(file->basename);
899         if (file->link) free(file->link);
900         if (file->sum) free(file->sum);
901         memset((char *)file, 0, sizeof(*file));
902 }
903
904
905 /*
906  * free up all elements in a flist
907  */
908 void flist_free(struct file_list *flist)
909 {
910         int i;
911         for (i=1;i<flist->count;i++) {
912                 free_file(flist->files[i]);
913                 free(flist->files[i]);
914         }       
915         memset((char *)flist->files, 0, sizeof(flist->files[0])*flist->count);
916         free(flist->files);
917         memset((char *)flist, 0, sizeof(*flist));
918         free(flist);
919 }
920
921
922 /*
923  * This routine ensures we don't have any duplicate names in our file list.
924  * duplicate names can cause corruption because of the pipelining 
925  */
926 static void clean_flist(struct file_list *flist, int strip_root)
927 {
928         int i;
929
930         if (!flist || flist->count == 0) 
931                 return;
932   
933         qsort(flist->files,flist->count,
934               sizeof(flist->files[0]),
935               (int (*)())file_compare);
936
937         for (i=1;i<flist->count;i++) {
938                 if (flist->files[i]->basename &&
939                     flist->files[i-1]->basename &&
940                     strcmp(f_name(flist->files[i]),
941                            f_name(flist->files[i-1])) == 0) {
942                         if (verbose > 1 && !am_server)
943                                 rprintf(FINFO,"removing duplicate name %s from file list %d\n",
944                                         f_name(flist->files[i-1]),i-1);
945                         free_file(flist->files[i]);
946                 } 
947         }
948
949         if (strip_root) {
950                 /* we need to strip off the root directory in the case
951                    of relative paths, but this must be done _after_
952                    the sorting phase */
953                 for (i=0;i<flist->count;i++) {
954                         if (flist->files[i]->dirname &&
955                             flist->files[i]->dirname[0] == '/') {
956                                 memmove(&flist->files[i]->dirname[0],
957                                         &flist->files[i]->dirname[1],
958                                         strlen(flist->files[i]->dirname));
959                         }
960                         
961                         if (flist->files[i]->dirname && 
962                             !flist->files[i]->dirname[0]) {
963                                 flist->files[i]->dirname = NULL;
964                         }
965                 }
966         }
967
968
969         if (verbose <= 3) return;
970
971         for (i=0;i<flist->count;i++) {
972                 rprintf(FINFO,"[%d] i=%d %s %s mode=0%o len=%d\n",
973                         getpid(), i, 
974                         NS(flist->files[i]->dirname),
975                         NS(flist->files[i]->basename),
976                         flist->files[i]->mode,
977                         (int)flist->files[i]->length);
978         }
979 }
980
981
982 /*
983  * return the full filename of a flist entry
984  */
985 char *f_name(struct file_struct *f)
986 {
987         static char names[10][MAXPATHLEN];
988         static int n;
989         char *p = names[n];
990
991         if (!f || !f->basename) return NULL;
992
993         n = (n+1)%10;
994
995         if (f->dirname) {
996                 strlcpy(p, f->dirname, MAXPATHLEN);
997                 strlcat(p, "/", MAXPATHLEN);
998                 strlcat(p, f->basename, MAXPATHLEN);
999         } else {
1000                 strlcpy(p, f->basename, MAXPATHLEN);
1001         }
1002
1003         return p;
1004 }
1005