Le 19 janv. 09 à 21:53, tim lindner a écrit :

Thanks for this. Everything has been working fine. I did encounter one problem. It didn't like it when colons were in filenames. Rsync would spit out an error and move to the next file.

I remember (sorry I don't have a reference) that HFS disallows a ":" in the file name. So when a filename is passed to the HFS driver from a subsystem (for example: Posix) that allows colons, the HFS code converts it to a slash "/" when storing the filename on disk.

If you pass a filename from a Posix API to a Carbon API you must convert any colons to slashes. So I added code to do this and it solved my problems. I added code to substitute colons for slashes inside fsreffrompath() in lib/sysxattrs.c

I hesitate to provide a patch because I am really unsure if I did it well. I copy the filename to a temporary string, do the substitution and then pass the temp string to CFStringCreateWithCString(). I think a better approach would be to scrap my changes and do the substitution on the buffer returned by CFStringGetCharacters(), before FSMakeFSRefUnicode is called. This would get rid of the new memory allocation.

But I am unsure how to do proper character substitution in a Unicode string.

--
tim lindner
tlindner!watermarkpress.com

Hello Tim,

You're welcome for the patch, glad it's still useful. And thank you for providing feedback on it.

":" and "/" in Mac OS X is a odd story. HFS filesystem and Mac OS until 9 use ":" as path separator (and this is the only forbidden character on a HFS filename). When moving to Mac OS X, Apple needed retrocompatibility and so they let the HFS filesystem as it was. But OS X is a UNIX OS, so it uses "/" as path separator, and the conversion of path separator is done on the fly between the OS and the filesystem.

On this rsync patch, we are talking directly with the filesystem, so you are right about converting path separators. As other functions take POSIX paths, it's weird for me that FSMakeFSRefUnicode needs a HFS like name and not a POSIX one. But I believe you!

You can modify my patch like this:
+       if(verbose > 3)
+               fprintf(stderr, "name=%s\n",startOfName);
        nameLength=strlen(startOfName);
        strcpy(name, startOfName);
        while(index<nameLength)
        {
                if(name[index]==':')
                        name[index]='/';
                index++;
        }
+ cfStringName=CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
+       if(cfStringName==NULL)

Putting this initialisation:
+       char parentPath[MAXPATHLEN+1], name[MAXNAMLEN+1];
        unsigned int index=0, nameLength;

It will need another buffer, but we would need anyway. We can't replace chars on CFStrings, we would need to pass by a CFMutableString (need another buffer). Or we would need to manipulate the Unicode string at the end, but I'm not sure how to do it. You could try:

+       CFStringGetCharacters(cfStringName, range, unicharName);
        while(index<range.length)
        {
                if(unicharName[index]==0x003B) /* == ':' */
                        unicharName[index]='0x002F'; /* == '/' */
                index++;
        }
+ carbon_error=FSMakeFSRefUnicode(&parentRef, range.length, unicharName, kTextEncodingUnknown, ref);

With only unsigned int index=0; as new initialization. 0x003B corresponds of the hexa code of : in unichar (UTF-16) and 0x002F corresponds to /. With some luck it will work.

I can't test as I haven't a Mac OS X.3 anymore. If you do it, can you please let me know?

Best regards,

Vitorio--
Please use reply-all for most replies to avoid omitting the mailing list.
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to