Mentioned new --keep-dirlinks option.
[rsync/rsync.git] / generator.c
index 01cba43..9cbfe75 100644 (file)
@@ -26,6 +26,7 @@
 extern int verbose;
 extern int dry_run;
 extern int relative_paths;
+extern int keep_dirlinks;
 extern int preserve_links;
 extern int am_root;
 extern int preserve_devices;
@@ -52,6 +53,8 @@ extern int only_existing;
 extern int orig_umask;
 extern int safe_symlinks;
 
+extern struct exclude_list_struct server_exclude_list;
+
 
 /* choose whether to skip a particular file */
 static int skip_file(char *fname, struct file_struct *file, STRUCT_STAT *st)
@@ -281,14 +284,34 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
        if (verbose > 2)
                rprintf(FINFO,"recv_generator(%s,%d)\n",fname,i);
 
+       if (server_exclude_list.head
+           && check_exclude(&server_exclude_list, fname,
+                            S_ISDIR(file->mode)) < 0) {
+               if (verbose) {
+                       rprintf(FINFO, "skipping server-excluded file \"%s\"\n",
+                               fname);
+               }
+               return;
+       }
+
        statret = link_stat(fname,&st);
 
        if (only_existing && statret == -1 && errno == ENOENT) {
                /* we only want to update existing files */
-               if (verbose > 1) rprintf(FINFO, "not creating new file \"%s\"\n",fname);
+               if (verbose > 1)
+                       rprintf(FINFO, "not creating new file \"%s\"\n", fname);
                return;
        }
 
+#if SUPPORT_LINKS
+       if (statret == 0 && keep_dirlinks
+           && S_ISLNK(st.st_mode) && S_ISDIR(file->mode)) {
+               STRUCT_STAT st2;
+               if (do_stat(fname, &st2) == 0 && S_ISDIR(st2.st_mode))
+                   st = st2;
+       }
+#endif
+
        if (statret == 0 &&
            !preserve_perms &&
            (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
@@ -325,9 +348,10 @@ void recv_generator(char *fname, struct file_struct *file, int i, int f_out)
                                        full_fname(fname));
                        }
                }
-               /* f_out is set to -1 when doing final directory
-                  permission and modification time repair */
-               if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
+               /* f_out is set to -1 when doing final directory-permission
+                * and modification-time repair. */
+               if (set_perms(fname, file, statret ? NULL : &st, 0)
+                   && verbose && f_out != -1)
                        rprintf(FINFO,"%s/\n",fname);
                return;
        }