Não é a solução mais elegante, mas você pode usar LD_PRELOAD para substituir as chamadas de sistema relevantes e forçar tudo para minúsculas. Eu achei divertido, então fiz uma pequena prova de conceito e ...
> ls in out
in:
CyltApJik keumyomDu LidusIcweo spydjiPa SycsEyror tusUngEg
out:
> rsync -av in/ --rsync-path='env LD_PRELOAD=$PWD/lowercase.so rsync' localhost:out/
sending incremental file list
./
CyltApJik
LidusIcweo
SycsEyror
keumyomDu
spydjiPa
tusUngEg
sent 372 bytes received 129 bytes 1002.00 bytes/sec
total size is 0 speedup is 0.00
> ls out
cyltapjik keumyomdu lidusicweo spydjipa sycseyror tusungeg
E aqui está a amostra, que pode levar algumas iterações para se tornar boa o suficiente para sincronizar tudo.
> cat lowercase.c
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define __USE_GNU
#include <dlfcn.h>
static int (*real_lstat) (const char *, struct stat *) = NULL;
static int (*real_rename)(const char *, const char *) = NULL;
char * lowered(const char * string)
{
char * low = strndup(string, 2048);
char * c;
if (low == NULL) return NULL;
for (c = low; *c; c++) {
*c = tolower(*c);
}
return low;
}
int lstat(const char * path, struct stat * buf)
{
int ret = 0;
if (real_lstat == NULL) {
real_lstat = dlsym(RTLD_NEXT, "lstat");
}
ret = real_lstat(path, buf);
if (ret == 0) return ret;
ret = real_lstat(lowered(path), buf);
return ret;
}
int rename (__const char *__old, __const char *__new)
{
if (real_rename == NULL) {
real_rename = dlsym(RTLD_NEXT, "rename");
}
return real_rename(__old, lowered(__new));
}
> gcc -ldl -fPIC -shared -o lowercase.so lowercase.c