bbe70fb0c01d8803e827e5aceaa2581e524b1e1b
[rsync/rsync.git] / generator.c
1 /* -*- c-file-style: "linux" -*-
2
3    rsync -- fast file replication program
4
5    Copyright (C) 1996-2000 by Andrew Tridgell
6    Copyright (C) Paul Mackerras 1996
7    Copyright (C) 2002 by Martin Pool <mbp@samba.org>
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "rsync.h"
25
26 extern int verbose;
27 extern int dry_run;
28 extern int relative_paths;
29 extern int keep_dirlinks;
30 extern int preserve_links;
31 extern int am_root;
32 extern int preserve_devices;
33 extern int preserve_hard_links;
34 extern int preserve_perms;
35 extern int preserve_uid;
36 extern int preserve_gid;
37 extern int preserve_times;
38 extern int omit_dir_times;
39 extern int delete_during;
40 extern int update_only;
41 extern int opt_ignore_existing;
42 extern int inplace;
43 extern int make_backups;
44 extern int csum_length;
45 extern int ignore_times;
46 extern int size_only;
47 extern OFF_T max_size;
48 extern int io_timeout;
49 extern int protocol_version;
50 extern int always_checksum;
51 extern char *partial_dir;
52 extern char *basis_dir[];
53 extern int compare_dest;
54 extern int link_dest;
55 extern int whole_file;
56 extern int local_server;
57 extern int list_only;
58 extern int read_batch;
59 extern int only_existing;
60 extern int orig_umask;
61 extern int safe_symlinks;
62 extern long block_size; /* "long" because popt can't set an int32. */
63
64 extern struct filter_list_struct server_filter_list;
65
66 static int unchanged_attrs(struct file_struct *file, STRUCT_STAT *st)
67 {
68         if (preserve_perms
69          && (st->st_mode & CHMOD_BITS) != (file->mode & CHMOD_BITS))
70                 return 0;
71
72         if (am_root && preserve_uid && st->st_uid != file->uid)
73                 return 0;
74
75         if (preserve_gid && file->gid != GID_NONE && st->st_gid != file->gid)
76                 return 0;
77
78         return 1;
79 }
80
81 /* Perform our quick-check heuristic for determining if a file is unchanged. */
82 static int unchanged_file(char *fn, struct file_struct *file, STRUCT_STAT *st)
83 {
84         if (st->st_size != file->length)
85                 return 0;
86
87         /* if always checksum is set then we use the checksum instead
88            of the file time to determine whether to sync */
89         if (always_checksum && S_ISREG(st->st_mode)) {
90                 char sum[MD4_SUM_LENGTH];
91                 file_checksum(fn, sum, st->st_size);
92                 return memcmp(sum, file->u.sum, protocol_version < 21 ? 2
93                                                         : MD4_SUM_LENGTH) == 0;
94         }
95
96         if (size_only)
97                 return 1;
98
99         if (ignore_times)
100                 return 0;
101
102         return cmp_modtime(st->st_mtime, file->modtime) == 0;
103 }
104
105
106 /*
107  * set (initialize) the size entries in the per-file sum_struct
108  * calculating dynamic block and checksum sizes.
109  *
110  * This is only called from generate_and_send_sums() but is a separate
111  * function to encapsulate the logic.
112  *
113  * The block size is a rounded square root of file length.
114  *
115  * The checksum size is determined according to:
116  *     blocksum_bits = BLOCKSUM_EXP + 2*log2(file_len) - log2(block_len)
117  * provided by Donovan Baarda which gives a probability of rsync
118  * algorithm corrupting data and falling back using the whole md4
119  * checksums.
120  *
121  * This might be made one of several selectable heuristics.
122  */
123 static void sum_sizes_sqroot(struct sum_struct *sum, int64 len)
124 {
125         int32 blength;
126         int s2length;
127
128         if (block_size)
129                 blength = block_size;
130         else if (len <= BLOCK_SIZE * BLOCK_SIZE)
131                 blength = BLOCK_SIZE;
132         else {
133                 int32 c;
134                 int64 l;
135                 int cnt;
136                 for (c = 1, l = len, cnt = 0; l >>= 2; c <<= 1, cnt++) {}
137                 if (cnt >= 31 || c >= MAX_BLOCK_SIZE)
138                         blength = MAX_BLOCK_SIZE;
139                 else {
140                     blength = 0;
141                     do {
142                             blength |= c;
143                             if (len < (int64)blength * blength)
144                                     blength &= ~c;
145                             c >>= 1;
146                     } while (c >= 8);   /* round to multiple of 8 */
147                     blength = MAX(blength, BLOCK_SIZE);
148                 }
149         }
150
151         if (protocol_version < 27) {
152                 s2length = csum_length;
153         } else if (csum_length == SUM_LENGTH) {
154                 s2length = SUM_LENGTH;
155         } else {
156                 int32 c;
157                 int64 l;
158                 int b = BLOCKSUM_BIAS;
159                 for (l = len; l >>= 1; b += 2) {}
160                 for (c = blength; c >>= 1 && b; b--) {}
161                 /* add a bit, subtract rollsum, round up. */
162                 s2length = (b + 1 - 32 + 7) / 8; /* --optimize in compiler-- */
163                 s2length = MAX(s2length, csum_length);
164                 s2length = MIN(s2length, SUM_LENGTH);
165         }
166
167         sum->flength    = len;
168         sum->blength    = blength;
169         sum->s2length   = s2length;
170         sum->count      = (len + (blength - 1)) / blength;
171         sum->remainder  = (len % blength);
172
173         if (sum->count && verbose > 2) {
174                 rprintf(FINFO,
175                         "count=%.0f rem=%ld blength=%ld s2length=%d flength=%.0f\n",
176                         (double)sum->count, (long)sum->remainder, (long)sum->blength,
177                         sum->s2length, (double)sum->flength);
178         }
179 }
180
181
182 /*
183  * Generate and send a stream of signatures/checksums that describe a buffer
184  *
185  * Generate approximately one checksum every block_len bytes.
186  */
187 static void generate_and_send_sums(int fd, OFF_T len, int f_out, int f_copy)
188 {
189         size_t i;
190         struct map_struct *mapbuf;
191         struct sum_struct sum;
192         OFF_T offset = 0;
193
194         sum_sizes_sqroot(&sum, len);
195
196         if (len > 0)
197                 mapbuf = map_file(fd, len, MAX_MAP_SIZE, sum.blength);
198         else
199                 mapbuf = NULL;
200
201         write_sum_head(f_out, &sum);
202
203         for (i = 0; i < sum.count; i++) {
204                 int32 n1 = (int32)MIN(len, (OFF_T)sum.blength);
205                 char *map = map_ptr(mapbuf, offset, n1);
206                 uint32 sum1 = get_checksum1(map, n1);
207                 char sum2[SUM_LENGTH];
208
209                 if (f_copy >= 0)
210                         full_write(f_copy, map, n1);
211
212                 get_checksum2(map, n1, sum2);
213
214                 if (verbose > 3) {
215                         rprintf(FINFO,
216                                 "chunk[%.0f] offset=%.0f len=%ld sum1=%08lx\n",
217                                 (double)i, (double)offset, (long)n1,
218                                 (unsigned long)sum1);
219                 }
220                 write_int(f_out, sum1);
221                 write_buf(f_out, sum2, sum.s2length);
222                 len -= n1;
223                 offset += n1;
224         }
225
226         if (mapbuf)
227                 unmap_file(mapbuf);
228 }
229
230
231 /* Acts on flist->file's ndx'th item, whose name is fname.  If a directory,
232  * make sure it exists, and has the right permissions/timestamp info.  For
233  * all other non-regular files (symlinks, etc.) we create them here.  For
234  * regular files that have changed, we try to find a basis file and then
235  * start sending checksums.
236  *
237  * Note that f_out is set to -1 when doing final directory-permission and
238  * modification-time repair. */
239 static void recv_generator(char *fname, struct file_list *flist,
240                            struct file_struct *file, int ndx,
241                            int f_out, int f_out_name)
242 {
243         int fd = -1, f_copy = -1;
244         STRUCT_STAT st, partial_st;
245         struct file_struct *back_file = NULL;
246         int statret, stat_errno;
247         char *fnamecmp, *partialptr, *backupptr = NULL;
248         char fnamecmpbuf[MAXPATHLEN];
249         uchar fnamecmp_type;
250
251         if (list_only)
252                 return;
253
254         if (verbose > 2)
255                 rprintf(FINFO, "recv_generator(%s,%d)\n", safe_fname(fname), ndx);
256
257         if (server_filter_list.head
258             && check_filter(&server_filter_list, fname,
259                             S_ISDIR(file->mode)) < 0) {
260                 if (verbose) {
261                         rprintf(FINFO, "skipping server-excluded file \"%s\"\n",
262                                 safe_fname(fname));
263                 }
264                 return;
265         }
266
267         if (dry_run > 1) {
268                 statret = -1;
269                 stat_errno = ENOENT;
270         } else {
271                 statret = link_stat(fname, &st,
272                                     keep_dirlinks && S_ISDIR(file->mode));
273                 stat_errno = errno;
274         }
275
276         if (only_existing && statret == -1 && stat_errno == ENOENT) {
277                 /* we only want to update existing files */
278                 if (verbose > 1) {
279                         rprintf(FINFO, "not creating new file \"%s\"\n",
280                                 safe_fname(fname));
281                 }
282                 return;
283         }
284
285         if (statret == 0 && !preserve_perms
286             && S_ISDIR(st.st_mode) == S_ISDIR(file->mode)) {
287                 /* if the file exists already and we aren't perserving
288                  * permissions then act as though the remote end sent
289                  * us the file permissions we already have */
290                 file->mode = (file->mode & ~CHMOD_BITS)
291                            | (st.st_mode & CHMOD_BITS);
292         }
293
294         if (S_ISDIR(file->mode)) {
295                 /* The file to be received is a directory, so we need
296                  * to prepare appropriately.  If there is already a
297                  * file of that name and it is *not* a directory, then
298                  * we need to delete it.  If it doesn't exist, then
299                  * (perhaps recursively) create it. */
300                 if (statret == 0 && !S_ISDIR(st.st_mode)) {
301                         delete_file(fname, DEL_TERSE);
302                         statret = -1;
303                 }
304                 if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
305                         if (!relative_paths || errno != ENOENT
306                             || create_directory_path(fname, orig_umask) < 0
307                             || do_mkdir(fname, file->mode) < 0) {
308                                 rsyserr(FERROR, errno,
309                                         "recv_generator: mkdir %s failed",
310                                         full_fname(fname));
311                         }
312                 }
313                 if (set_perms(fname, file, statret ? NULL : &st, 0)
314                     && verbose && f_out != -1)
315                         rprintf(FINFO, "%s/\n", safe_fname(fname));
316                 if (delete_during && f_out != -1 && csum_length != SUM_LENGTH
317                     && (file->flags & FLAG_DEL_HERE))
318                         delete_in_dir(flist, fname, file);
319                 return;
320         } else if (max_size && file->length > max_size) {
321                 if (verbose > 1)
322                         rprintf(FINFO, "%s is over max-size\n", fname);
323                 return;
324         }
325
326         if (preserve_links && S_ISLNK(file->mode)) {
327 #if SUPPORT_LINKS
328                 if (safe_symlinks && unsafe_symlink(file->u.link, fname)) {
329                         if (verbose) {
330                                 rprintf(FINFO, "ignoring unsafe symlink %s -> \"%s\"\n",
331                                         full_fname(fname), file->u.link);
332                         }
333                         return;
334                 }
335                 if (statret == 0) {
336                         int dflag = S_ISDIR(st.st_mode) ? DEL_DIR : 0;
337                         char lnk[MAXPATHLEN];
338                         int len;
339
340                         if (!dflag
341                             && (len = readlink(fname, lnk, MAXPATHLEN-1)) > 0) {
342                                 lnk[len] = 0;
343                                 /* A link already pointing to the
344                                  * right place -- no further action
345                                  * required. */
346                                 if (strcmp(lnk, file->u.link) == 0) {
347                                         set_perms(fname, file, &st,
348                                                   PERMS_REPORT);
349                                         return;
350                                 }
351                         }
352                         /* Not the right symlink (or not a symlink), so
353                          * delete it. */
354                         delete_file(fname, dflag | DEL_TERSE);
355                 }
356                 if (do_symlink(file->u.link,fname) != 0) {
357                         rsyserr(FERROR, errno, "symlink %s -> \"%s\" failed",
358                                 full_fname(fname), safe_fname(file->u.link));
359                 } else {
360                         set_perms(fname,file,NULL,0);
361                         if (verbose) {
362                                 rprintf(FINFO, "%s -> %s\n", safe_fname(fname),
363                                         safe_fname(file->u.link));
364                         }
365                 }
366 #endif
367                 return;
368         }
369
370         if (am_root && preserve_devices && IS_DEVICE(file->mode)) {
371                 if (statret != 0 ||
372                     st.st_mode != file->mode ||
373                     st.st_rdev != file->u.rdev) {
374                         int dflag = S_ISDIR(st.st_mode) ? DEL_DIR : 0;
375                         delete_file(fname, dflag | DEL_TERSE);
376                         if (verbose > 2) {
377                                 rprintf(FINFO,"mknod(%s,0%o,0x%x)\n",
378                                         safe_fname(fname),
379                                         (int)file->mode, (int)file->u.rdev);
380                         }
381                         if (do_mknod(fname,file->mode,file->u.rdev) != 0) {
382                                 rsyserr(FERROR, errno, "mknod %s failed",
383                                         full_fname(fname));
384                         } else {
385                                 set_perms(fname,file,NULL,0);
386                                 if (verbose) {
387                                         rprintf(FINFO, "%s\n",
388                                                 safe_fname(fname));
389                                 }
390                         }
391                 } else {
392                         set_perms(fname, file, &st, PERMS_REPORT);
393                 }
394                 return;
395         }
396
397         if (preserve_hard_links && hard_link_check(file, HL_CHECK_MASTER))
398                 return;
399
400         if (!S_ISREG(file->mode)) {
401                 rprintf(FINFO, "skipping non-regular file \"%s\"\n",
402                         safe_fname(fname));
403                 return;
404         }
405
406         fnamecmp = fname;
407         fnamecmp_type = FNAMECMP_FNAME;
408
409         if (statret == -1 && basis_dir[0] != NULL) {
410                 int fallback_match = -1;
411                 int match_level = 0;
412                 int i = 0;
413                 do {
414                         pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
415                                  basis_dir[i], fname);
416                         if (link_stat(fnamecmpbuf, &st, 0) == 0
417                             && S_ISREG(st.st_mode)) {
418                                 statret = 0;
419                                 if (link_dest) {
420                                         if (!match_level) {
421                                                 fallback_match = i;
422                                                 match_level = 1;
423                                         } else if (match_level == 2
424                                             && !unchanged_attrs(file, &st))
425                                                 continue;
426                                         if (!unchanged_file(fnamecmpbuf, file, &st))
427                                                 continue;
428                                         fallback_match = i;
429                                         match_level = 2;
430                                         if (!unchanged_attrs(file, &st))
431                                                 continue;
432                                 }
433                                 match_level = 3;
434                                 break;
435                         }
436                 } while (basis_dir[++i] != NULL);
437                 if (statret == 0) {
438                         if (match_level < 3) {
439                                 i = fallback_match;
440                                 pathjoin(fnamecmpbuf, sizeof fnamecmpbuf,
441                                          basis_dir[i], fname);
442                         }
443 #if HAVE_LINK
444                         if (link_dest && match_level == 3 && !dry_run) {
445                                 if (do_link(fnamecmpbuf, fname) < 0) {
446                                         if (verbose) {
447                                                 rsyserr(FINFO, errno,
448                                                         "link %s => %s",
449                                                         fnamecmpbuf,
450                                                         safe_fname(fname));
451                                         }
452                                         fnamecmp = fnamecmpbuf;
453                                         fnamecmp_type = i;
454                                 }
455                         } else
456 #endif
457                         {
458                                 fnamecmp = fnamecmpbuf;
459                                 fnamecmp_type = i;
460                         }
461                 }
462         }
463
464         if (statret == 0 && !S_ISREG(st.st_mode)) {
465                 int dflag = S_ISDIR(st.st_mode) ? DEL_DIR : 0;
466                 if (delete_file(fname, dflag | DEL_TERSE) != 0)
467                         return;
468                 statret = -1;
469                 stat_errno = ENOENT;
470         }
471
472         if (partial_dir && (partialptr = partial_dir_fname(fname)) != NULL
473             && link_stat(partialptr, &partial_st, 0) == 0
474             && S_ISREG(partial_st.st_mode)) {
475                 if (statret == -1)
476                         goto prepare_to_open;
477         } else
478                 partialptr = NULL;
479
480         if (statret == -1) {
481                 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
482                         return;
483                 if (stat_errno == ENOENT)
484                         goto notify_others;
485                 if (verbose > 1) {
486                         rsyserr(FERROR, stat_errno,
487                                 "recv_generator: failed to stat %s",
488                                 full_fname(fname));
489                 }
490                 return;
491         }
492
493         if (opt_ignore_existing && fnamecmp_type == FNAMECMP_FNAME) {
494                 if (verbose > 1)
495                         rprintf(FINFO, "%s exists\n", safe_fname(fname));
496                 return;
497         }
498
499         if (update_only && fnamecmp_type == FNAMECMP_FNAME
500             && cmp_modtime(st.st_mtime, file->modtime) > 0) {
501                 if (verbose > 1)
502                         rprintf(FINFO, "%s is newer\n", safe_fname(fname));
503                 return;
504         }
505
506         if (!compare_dest && fnamecmp_type <= FNAMECMP_BASIS_DIR_HIGH)
507                 ;
508         else if (unchanged_file(fnamecmp, file, &st)) {
509                 if (fnamecmp_type == FNAMECMP_FNAME)
510                         set_perms(fname, file, &st, PERMS_REPORT);
511                 return;
512         }
513
514 prepare_to_open:
515         if (partialptr) {
516                 st = partial_st;
517                 fnamecmp = partialptr;
518                 fnamecmp_type = FNAMECMP_PARTIAL_DIR;
519                 statret = 0;
520         }
521
522         if (dry_run || whole_file > 0) {
523                 statret = -1;
524                 goto notify_others;
525         }
526         if (read_batch)
527                 goto notify_others;
528
529         /* open the file */
530         fd = do_open(fnamecmp, O_RDONLY, 0);
531
532         if (fd == -1) {
533                 rsyserr(FERROR, errno, "failed to open %s, continuing",
534                         full_fname(fnamecmp));
535             pretend_missing:
536                 /* pretend the file didn't exist */
537                 if (preserve_hard_links && hard_link_check(file, HL_SKIP))
538                         return;
539                 statret = -1;
540                 goto notify_others;
541         }
542
543         if (inplace && make_backups) {
544                 if (!(backupptr = get_backup_name(fname))) {
545                         close(fd);
546                         return;
547                 }
548                 if (!(back_file = make_file(fname, NULL, NO_FILTERS))) {
549                         close(fd);
550                         goto pretend_missing;
551                 }
552                 if (robust_unlink(backupptr) && errno != ENOENT) {
553                         rsyserr(FERROR, errno, "unlink %s",
554                                 full_fname(backupptr));
555                         free(back_file);
556                         close(fd);
557                         return;
558                 }
559                 if ((f_copy = do_open(backupptr,
560                     O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0600)) < 0) {
561                         rsyserr(FERROR, errno, "open %s",
562                                 full_fname(backupptr));
563                         free(back_file);
564                         close(fd);
565                         return;
566                 }
567                 fnamecmp_type = FNAMECMP_BACKUP;
568         }
569
570         if (verbose > 3) {
571                 rprintf(FINFO, "gen mapped %s of size %.0f\n",
572                         safe_fname(fnamecmp), (double)st.st_size);
573         }
574
575         if (verbose > 2)
576                 rprintf(FINFO, "generating and sending sums for %d\n", ndx);
577
578 notify_others:
579         write_int(f_out, ndx);
580         if (protocol_version >= 29 && inplace && !read_batch)
581                 write_byte(f_out, fnamecmp_type);
582         if (f_out_name >= 0)
583                 write_byte(f_out_name, fnamecmp_type);
584
585         if (dry_run || read_batch)
586                 return;
587
588         if (statret == 0) {
589                 generate_and_send_sums(fd, st.st_size, f_out, f_copy);
590
591                 if (f_copy >= 0) {
592                         close(f_copy);
593                         set_perms(backupptr, back_file, NULL, 0);
594                         if (verbose > 1) {
595                                 rprintf(FINFO, "backed up %s to %s\n",
596                                         fname, backupptr);
597                         }
598                         free(back_file);
599                 }
600
601                 close(fd);
602         } else
603                 write_sum_head(f_out, NULL);
604 }
605
606
607 void generate_files(int f_out, struct file_list *flist, char *local_name,
608                     int f_out_name)
609 {
610         int i;
611         int phase = 0;
612         char fbuf[MAXPATHLEN];
613         int need_retouch_dir_times = preserve_times && !omit_dir_times;
614         int need_retouch_dir_perms = 0;
615         int save_only_existing = only_existing;
616         int save_opt_ignore_existing = opt_ignore_existing;
617
618         if (verbose > 2) {
619                 rprintf(FINFO, "generator starting pid=%ld count=%d\n",
620                         (long)getpid(), flist->count);
621         }
622
623         if (verbose >= 2) {
624                 rprintf(FINFO,
625                         whole_file > 0
626                         ? "delta-transmission disabled for local transfer or --whole-file\n"
627                         : "delta transmission enabled\n");
628         }
629
630         /* We expect to just sit around now, so don't exit on a timeout.
631          * If we really get a timeout then the other process should exit. */
632         io_timeout = 0;
633
634         for (i = 0; i < flist->count; i++) {
635                 struct file_struct *file = flist->files[i];
636                 struct file_struct copy;
637
638                 if (!file->basename)
639                         continue;
640
641                 /* We need to ensure that any dirs we create have writeable
642                  * permissions during the time we are putting files within
643                  * them.  This is then fixed after the transfer is done. */
644                 if (!am_root && S_ISDIR(file->mode) && !(file->mode & S_IWUSR)) {
645                         copy = *file;
646                         copy.mode |= S_IWUSR; /* user write */
647                         file = &copy;
648                         need_retouch_dir_perms = 1;
649                 }
650
651                 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
652                                flist, file, i, f_out, f_out_name);
653         }
654         if (delete_during)
655                 delete_in_dir(NULL, NULL, NULL);
656
657         phase++;
658         csum_length = SUM_LENGTH;
659         only_existing = max_size = opt_ignore_existing = 0;
660         update_only = always_checksum = size_only = 0;
661         ignore_times = 1;
662
663         if (verbose > 2)
664                 rprintf(FINFO,"generate_files phase=%d\n",phase);
665
666         write_int(f_out, -1);
667
668         /* files can cycle through the system more than once
669          * to catch initial checksum errors */
670         while ((i = get_redo_num()) != -1) {
671                 struct file_struct *file = flist->files[i];
672                 recv_generator(local_name ? local_name : f_name_to(file, fbuf),
673                                flist, file, i, f_out, f_out_name);
674         }
675
676         phase++;
677         only_existing = save_only_existing;
678         opt_ignore_existing = save_opt_ignore_existing;
679
680         if (verbose > 2)
681                 rprintf(FINFO,"generate_files phase=%d\n",phase);
682
683         write_int(f_out, -1);
684
685         /* Read post-redo-phase MSG_DONE and any prior messages. */
686         get_redo_num();
687
688         if (preserve_hard_links)
689                 do_hard_links();
690
691         if ((need_retouch_dir_perms || need_retouch_dir_times)
692             && !list_only && !local_name && !dry_run) {
693                 /* Now we need to fix any directory permissions that were
694                  * modified during the transfer and/or re-set any tweaked
695                  * modified-time values. */
696                 for (i = 0; i < flist->count; i++) {
697                         struct file_struct *file = flist->files[i];
698                         if (!file->basename || !S_ISDIR(file->mode))
699                                 continue;
700                         if (!need_retouch_dir_times && file->mode & S_IWUSR)
701                                 continue;
702                         recv_generator(local_name ? local_name : f_name(file),
703                                        flist, file, i, -1, -1);
704                 }
705         }
706
707         if (verbose > 2)
708                 rprintf(FINFO,"generate_files finished\n");
709 }