e068fefcae6978cdad46d5d0e721894637a30ad2
[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 --- orig/lib/wildmatch.c        2003-07-14 15:12:59
40 +++ lib/wildmatch.c     2004-06-18 17:27:00
41 @@ -76,8 +76,20 @@ static int domatch(const unsigned char *
42             ch = *++p;
43             /* FALLTHROUGH */
44           default:
45 -           if (*text != ch)
46 +           if (*text != ch) {
47 +               extern int ignore_case;
48 +               if (ignore_case) {
49 +                   if (ISUPPER(*text)) {
50 +                       if (tolower(*text) == ch)
51 +                           continue;
52 +                   }
53 +                   else if (ISUPPER(ch)) {
54 +                       if (*text == tolower(ch))
55 +                           continue;
56 +                   }
57 +               }
58                 return FALSE;
59 +           }
60             continue;
61           case '?':
62             /* Match anything but '/'. */
63 --- orig/options.c      2004-06-20 19:30:00
64 +++ options.c   2004-07-03 20:19:20
65 @@ -92,6 +92,7 @@ int opt_ignore_existing = 0;
66  int max_delete = 0;
67  int ignore_errors = 0;
68  int modify_window = 0;
69 +int ignore_case = 0;
70  int blocking_io = -1;
71  int checksum_seed = 0;
72  unsigned int block_size = 0;
73 @@ -279,6 +280,7 @@ void usage(enum logcode F)
74    rprintf(F,"     --include-from=FILE     don't exclude patterns listed in FILE\n");
75    rprintf(F,"     --files-from=FILE       read FILE for list of source-file names\n");
76    rprintf(F," -0  --from0                 all *-from file lists are delimited by nulls\n");
77 +  rprintf(F,"     --ignore-case           ignore case when comparing filenames\n");
78    rprintf(F,"     --version               print version number\n");
79    rprintf(F,"     --daemon                run as an rsync daemon\n");
80    rprintf(F,"     --no-detach             do not detach from the parent\n");
81 @@ -334,6 +336,7 @@ static struct poptOption long_options[] 
82    {"include",          0,  POPT_ARG_STRING, 0,              OPT_INCLUDE, 0, 0 },
83    {"exclude-from",     0,  POPT_ARG_STRING, 0,              OPT_EXCLUDE_FROM, 0, 0 },
84    {"include-from",     0,  POPT_ARG_STRING, 0,              OPT_INCLUDE_FROM, 0, 0 },
85 +  {"ignore-case",      0,  POPT_ARG_NONE,   &ignore_case, 0, 0, 0 },
86    {"safe-links",       0,  POPT_ARG_NONE,   &safe_symlinks, 0, 0, 0 },
87    {"help",            'h', POPT_ARG_NONE,   0,              'h', 0, 0 },
88    {"backup",          'b', POPT_ARG_NONE,   &make_backups, 0, 0, 0 },
89 @@ -936,6 +939,9 @@ void server_options(char **args,int *arg
90                 args[ac++] = arg;
91         }
92  
93 +       if (ignore_case)
94 +               args[ac++] = "--ignore-case";
95 +
96         if (keep_partial)
97                 args[ac++] = "--partial";
98  
99 --- orig/util.c 2004-06-09 21:54:47
100 +++ util.c      2004-07-03 20:19:20
101 @@ -951,6 +951,19 @@ int u_strcmp(const char *cs1, const char
102  {
103         const uchar *s1 = (const uchar *)cs1;
104         const uchar *s2 = (const uchar *)cs2;
105 +       extern int ignore_case;
106 +       
107 +       if (ignore_case) {
108 +               while (*s1 && *s2) {
109 +                       uchar c1 = islower(*s1) ? toupper(*s1) : *s1;
110 +                       uchar c2 = islower(*s2) ? toupper(*s2) : *s2;
111 +                       if (c1 != c2)
112 +                               return (int)c1 - (int)c2;
113 +                       s1++; s2++;
114 +               }
115 +
116 +               return (int)*s1 - (int)*s2;
117 +       }
118  
119         while (*s1 && *s2 && (*s1 == *s2)) {
120                 s1++; s2++;