rsync 3.0.4 patches for 10.3

macuserfr macuserfr at free.fr
Tue Jan 20 11:56:27 GMT 2009


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


More information about the rsync mailing list