More updates.
[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.
19
20 A few caveats - both ends have to support the option - I couldn't make
21 it backwards compatible because both ends exchange information about a
22 sorted file list that has to sort the same way on either side (which
23 very subtly bit me when I first did this).  I also didn't bump the
24 protocol in this patch (wasn't quite sure it was appropriate just for an
25 incompatible command line option) since it was for local use.
26
27 NOTE: patch updated for latest CVS source by Wayne Davison, but UNTESTED!
28
29 -- David
30
31 /-----------------------------------------------------------------------\
32  \               David Bolen            \   E-mail: db3l@fitlinxx.com  /
33   |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
34  /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
35 \-----------------------------------------------------------------------/
36
37           - - - - - - - - - - - - - - - - - - - - - - - - -
38
39 --- options.c   17 Apr 2004 17:07:23 -0000      1.147
40 +++ options.c   22 Apr 2004 23:44:15 -0000
41 @@ -89,6 +89,7 @@ int opt_ignore_existing = 0;
42  int max_delete = 0;
43  int ignore_errors = 0;
44  int modify_window = 0;
45 +int ignore_case = 0;
46  int blocking_io = -1;
47  int checksum_seed = 0;
48  unsigned int block_size = 0;
49 @@ -275,6 +276,7 @@ void usage(enum logcode F)
50    rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
51    rprintf(F,"     --files-from=FILE       read FILE for list of source-file names\n");
52    rprintf(F," -0  --from0                 all *-from file lists are delimited by nulls\n");
53 +  rprintf(F,"     --ignore-case           ignore case when comparing filenames\n");
54    rprintf(F,"     --version               print version number\n");
55    rprintf(F,"     --daemon                run as an rsync daemon\n");
56    rprintf(F,"     --no-detach             do not detach from the parent\n");
57 @@ -329,6 +331,7 @@ static struct poptOption long_options[] 
58    {"include",          0,  POPT_ARG_STRING, 0,              OPT_INCLUDE, 0, 0 },
59    {"exclude-from",     0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE_FROM, 0, 0 },
60    {"include-from",     0,  POPT_ARG_STRING, 0,              OPT_INCLUDE_FROM, 0, 0 },
61 +  {"ignore-case",      0,  POPT_ARG_NONE,   &ignore_case, 0, 0, 0 },
62    {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
63    {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0 },
64    {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
65 @@ -911,6 +914,9 @@ void server_options(char **args,int *arg
66                         goto oom;
67                 args[ac++] = arg;
68         }
69 +
70 +       if (ignore_case)
71 +               args[ac++] = "--ignore-case";
72  
73         if (keep_partial)
74                 args[ac++] = "--partial";
75 --- util.c      22 Apr 2004 22:17:15 -0000      1.138
76 +++ util.c      22 Apr 2004 23:44:15 -0000
77 @@ -924,6 +924,19 @@ int u_strcmp(const char *cs1, const char
78  {
79         const uchar *s1 = (const uchar *)cs1;
80         const uchar *s2 = (const uchar *)cs2;
81 +       extern int ignore_case;
82 +       
83 +       if (ignore_case) {
84 +               while (*s1 && *s2) {
85 +                       uchar c1 = islower(*s1) ? toupper(*s1) : *s1;
86 +                       uchar c2 = islower(*s2) ? toupper(*s2) : *s2;
87 +                       if (c1 != c2)
88 +                               return (int)c1 - (int)c2;
89 +                       s1++; s2++;
90 +               }
91 +
92 +               return (int)*s1 - (int)*s2;
93 +       }
94  
95         while (*s1 && *s2 && (*s1 == *s2)) {
96                 s1++; s2++;
97 --- lib/wildmatch.c     14 Jul 2003 15:12:59 -0000      1.12
98 +++ lib/wildmatch.c     22 Apr 2004 23:44:15 -0000
99 @@ -76,8 +76,20 @@ static int domatch(const unsigned char *
100             ch = *++p;
101             /* FALLTHROUGH */
102           default:
103 -           if (*text != ch)
104 +           if (*text != ch) {
105 +               extern int ignore_case;
106 +               if (ignore_case) {
107 +                   if (ISUPPER(*text)) {
108 +                       if (tolower(*text) == ch)
109 +                           continue;
110 +                   }
111 +                   else if (ISUPPER(ch)) {
112 +                       if (*text == tolower(ch))
113 +                           continue;
114 +                   }
115 +               }
116                 return FALSE;
117 +           }
118             continue;
119           case '?':
120             /* Match anything but '/'. */