54458616e1284bf61b1332c03a3111896e9bd64d
[rsync/rsync-patches.git] / keep-dirlinks.diff
1 --- generator.c 18 May 2004 08:50:17 -0000      1.85
2 +++ generator.c 5 Jun 2004 15:56:04 -0000
3 @@ -26,6 +26,7 @@
4  extern int verbose;
5  extern int dry_run;
6  extern int relative_paths;
7 +extern int keep_dirlinks;
8  extern int preserve_links;
9  extern int am_root;
10  extern int preserve_devices;
11 @@ -302,6 +303,15 @@ void recv_generator(char *fname, struct 
12                 return;
13         }
14  
15 +#if SUPPORT_LINKS
16 +       if (statret == 0 && keep_dirlinks
17 +           && S_ISLNK(st.st_mode) && S_ISDIR(file->mode)) {
18 +               STRUCT_STAT st2;
19 +               if (do_stat(fname, &st2) == 0 && S_ISDIR(st2.st_mode))
20 +                   st = st2;
21 +       }
22 +#endif
23 +
24         if (statret == 0 &&
25             !preserve_perms &&
26             (S_ISDIR(st.st_mode) == S_ISDIR(file->mode))) {
27 @@ -329,18 +339,23 @@ void recv_generator(char *fname, struct 
28                         }
29                         statret = -1;
30                 }
31 -               if (statret != 0 && do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
32 -                       if (!(relative_paths && errno == ENOENT
33 -                           && create_directory_path(fname, orig_umask) == 0
34 -                           && do_mkdir(fname, file->mode) == 0)) {
35 -                               rsyserr(FERROR, errno,
36 -                                       "recv_generator: mkdir %s failed",
37 -                                       full_fname(fname));
38 +               if (statret != 0) {
39 +                       if (do_mkdir(fname,file->mode) != 0 && errno != EEXIST) {
40 +                               if (!(relative_paths && errno == ENOENT
41 +                                   && create_directory_path(fname, orig_umask) == 0
42 +                                   && do_mkdir(fname, file->mode) == 0)) {
43 +                                       rsyserr(FERROR, errno,
44 +                                               "recv_generator: mkdir %s failed",
45 +                                               full_fname(fname));
46 +                               }
47                         }
48 +                       statret = link_stat(fname, &st);
49 +                       if (statret != 0)
50 +                               return;
51                 }
52 -               /* f_out is set to -1 when doing final directory
53 -                  permission and modification time repair */
54 -               if (set_perms(fname,file,NULL,0) && verbose && (f_out != -1))
55 +               /* f_out is set to -1 when doing final directory-permission
56 +                * and modification-time repair. */
57 +               if (set_perms(fname, file, &st, 0) && verbose && (f_out != -1))
58                         rprintf(FINFO,"%s/\n",fname);
59                 return;
60         }
61 --- options.c   27 May 2004 21:51:53 -0000      1.153
62 +++ options.c   5 Jun 2004 15:56:04 -0000
63 @@ -38,6 +38,7 @@ int make_backups = 0;
64  int whole_file = -1;
65  
66  int archive_mode = 0;
67 +int keep_dirlinks = 0;
68  int copy_links = 0;
69  int preserve_links = 0;
70  int preserve_hard_links = 0;
71 @@ -232,6 +233,7 @@ void usage(enum logcode F)
72    rprintf(F,"     --backup-dir            make backups into this directory\n");
73    rprintf(F,"     --suffix=SUFFIX         backup suffix (default %s w/o --backup-dir)\n",BACKUP_SUFFIX);
74    rprintf(F," -u, --update                update only (don't overwrite newer files)\n");
75 +  rprintf(F," -K, --keep-dirlinks         treat symlinked dir on receiver as dir\n");
76    rprintf(F," -l, --links                 copy symlinks as symlinks\n");
77    rprintf(F," -L, --copy-links            copy the referent of all symlinks\n");
78    rprintf(F,"     --copy-unsafe-links     copy the referent of \"unsafe\" symlinks\n");
79 @@ -338,6 +340,7 @@ static struct poptOption long_options[] 
80    {"sparse",          'S', POPT_ARG_NONE,   &sparse_files, 0, 0, 0 },
81    {"cvs-exclude",     'C', POPT_ARG_NONE,   &cvs_exclude, 0, 0, 0 },
82    {"update",          'u', POPT_ARG_NONE,   &update_only, 0, 0, 0 },
83 +  {"keep-dirlinks",   'K', POPT_ARG_NONE,   &keep_dirlinks, 0, 0, 0 },
84    {"links",           'l', POPT_ARG_NONE,   &preserve_links, 0, 0, 0 },
85    {"copy-links",      'L', POPT_ARG_NONE,   &copy_links, 0, 0, 0 },
86    {"whole-file",      'W', POPT_ARG_VAL,    &whole_file, 1, 0, 0 },
87 @@ -818,6 +821,8 @@ void server_options(char **args,int *arg
88                 argstr[x++] = 'l';
89         if (copy_links)
90                 argstr[x++] = 'L';
91 +       if (keep_dirlinks && am_sender)
92 +               argstr[x++] = 'K';
93  
94         if (whole_file > 0)
95                 argstr[x++] = 'W';
96 --- rsync.yo    21 May 2004 09:44:32 -0000      1.170
97 +++ rsync.yo    5 Jun 2004 15:56:05 -0000
98 @@ -289,6 +289,7 @@ verb(
99       --backup-dir            make backups into this directory
100       --suffix=SUFFIX         backup suffix (default ~ w/o --backup-dir)
101   -u, --update                update only (don't overwrite newer files)
102 + -K, --keep-dirlinks         treat symlinked dir on receiver as dir
103   -l, --links                 copy symlinks as symlinks
104   -L, --copy-links            copy the referent of all symlinks
105       --copy-unsafe-links     copy the referent of "unsafe" symlinks
106 @@ -479,6 +480,10 @@ symlink where the destination has a file
107  regardless of the timestamps.  This might change in the future (feel
108  free to comment on this on the mailing list if you have an opinion).
109  
110 +dit(bf(-K, --keep-dirlinks)) On the receiving side, if a symlink is
111 +pointing to a directory, it will be treated as matching a directory
112 +from the sender.
113 +
114  dit(bf(-l, --links)) When symlinks are encountered, recreate the
115  symlink on the destination.
116