Updated to apply to latest CVS source.
[rsync/rsync-patches.git] / ignore-case.diff
1 From: David Bolen <db3l@fitlinxx.com>
2 To: Peter Tattam <peter@jazz-1.trumpet.com.au>
3 Cc: rsync@lists.samba.org
4 Subject: RE: mixed case file systems.
5 Date: Thu, 18 Apr 2002 23:04:06 -0400
6
7 Peter Tattam [peter@jazz-1.trumpet.com.au] writes:
8
9 > I believe a suitable workaround would be to ignore case for file names
10 > when the rsync process is undertaken.  Is this facility available or
11 > planned in the near future?
12
13 I've attached a context diff for some changes I made to our local copy
14 a while back to add an "--ignore-case" option just for this purpose.
15 In our case it came up in the context of disting between NTFS and FAT
16 remote systems.  I think we ended up not needing it, but it does make
17 rsync match filenames in a case insensitive manner, so it might at
18 least be worth trying to see if it resolves your issue. [NOTE: patch
19 updated for latest CVS source way Wayne Davison, but UNTESTED!]
20
21 A few caveats - both ends have to support the option - I couldn't make
22 it backwards compatible because both ends exchange information about a
23 sorted file list that has to sort the same way on either side (which
24 very subtly bit me when I first did this).  I also didn't bump the
25 protocol in this patch (wasn't quite sure it was appropriate just for an
26 incompatible command line option) since since it was for local use.
27
28 The patch is based on a 2.4.x series rsync, but if it doesn't apply
29 cleanly to 2.5.x, it's should be simple enough to just apply manually.
30
31 -- David
32
33 /-----------------------------------------------------------------------\
34  \               David Bolen            \   E-mail: db3l@fitlinxx.com  /
35   |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
36  /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
37 \-----------------------------------------------------------------------/
38
39           - - - - - - - - - - - - - - - - - - - - - - - - -
40
41 Index: options.c
42 --- options.c   22 Feb 2004 08:56:43 -0000      1.139
43 +++ options.c   23 Feb 2004 19:25:19 -0000
44 @@ -87,6 +87,7 @@ int opt_ignore_existing = 0;
45  int max_delete = 0;
46  int ignore_errors = 0;
47  int modify_window = 0;
48 +int ignore_case = 0;
49  int blocking_io = -1;
50  int checksum_seed = 0;
51  unsigned int block_size = 0;
52 @@ -273,6 +274,7 @@ void usage(enum logcode F)
53    rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
54    rprintf(F,"     --files-from=FILE       read FILE for list of source-file names\n");
55    rprintf(F," -0  --from0                 all *-from file lists are delimited by nulls\n");
56 +  rprintf(F,"     --ignore-case           ignore case when comparing filenames\n");
57    rprintf(F,"     --version               print version number\n");
58    rprintf(F,"     --daemon                run as an rsync daemon\n");
59    rprintf(F,"     --no-detach             do not detach from the parent\n");
60 @@ -327,6 +329,7 @@ static struct poptOption long_options[] 
61    {"include",          0,  POPT_ARG_STRING, 0,              OPT_INCLUDE, 0, 0 },
62    {"exclude-from",     0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE_FROM, 0, 0 },
63    {"include-from",     0,  POPT_ARG_STRING, 0,              OPT_INCLUDE_FROM, 0, 0 },
64 +  {"ignore-case",      0,  POPT_ARG_NONE,   &ignore_case, 0, 0, 0 },
65    {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
66    {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0 },
67    {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
68 @@ -892,6 +895,9 @@ void server_options(char **args,int *arg
69                         goto oom;
70                 args[ac++] = arg;
71         }
72 +
73 +       if (ignore_case)
74 +               args[ac++] = "--ignore-case";
75  
76         if (keep_partial)
77                 args[ac++] = "--partial";
78 Index: util.c
79 --- util.c      17 Feb 2004 23:13:10 -0000      1.132
80 +++ util.c      23 Feb 2004 19:25:20 -0000
81 @@ -890,6 +890,19 @@ int u_strcmp(const char *cs1, const char
82  {
83         const uchar *s1 = (const uchar *)cs1;
84         const uchar *s2 = (const uchar *)cs2;
85 +       extern int ignore_case;
86 +       
87 +       if (ignore_case) {
88 +               while (*s1 && *s2) {
89 +                       uchar c1 = islower(*s1) ? toupper(*s1) : *s1;
90 +                       uchar c2 = islower(*s2) ? toupper(*s2) : *s2;
91 +                       if (c1 != c2)
92 +                               return c1 - c2;
93 +                       s1++; s2++;
94 +               }
95 +
96 +               return (int)*s1 - (int)*s2;
97 +       }
98  
99         while (*s1 && *s2 && (*s1 == *s2)) {
100                 s1++; s2++;
101 Index: lib/wildmatch.c
102 --- lib/wildmatch.c     14 Jul 2003 15:12:59 -0000      1.12
103 +++ lib/wildmatch.c     23 Feb 2004 19:25:20 -0000
104 @@ -76,8 +76,20 @@ static int domatch(const unsigned char *
105             ch = *++p;
106             /* FALLTHROUGH */
107           default:
108 -           if (*text != ch)
109 +           if (*text != ch) {
110 +               extern int ignore_case;
111 +               if (ignore_case) {
112 +                   if (ISUPPER(*text)) {
113 +                       if (tolower(*text) == ch)
114 +                           continue;
115 +                   }
116 +                   else if (ISUPPER(ch)) {
117 +                       if (*text == tolower(ch))
118 +                           continue;
119 +                   }
120 +               }
121                 return FALSE;
122 +           }
123             continue;
124           case '?':
125             /* Match anything but '/'. */