osx 10.6 strange rsync errors

Ira Cooke iracooke at googlemail.com
Thu Feb 24 02:54:07 MST 2011


I've recently encountered this issue which was discussed here about a year ago. 

I'm not sure if anyone has a fix for this, but I thought I would post my workaround here. 

Since the topic is old, I'm summarising the problem .. basically it involves rsync creating large numbers of files with a leading ".." when syncing to an apple network share via afp. 

The essence of the problem is that there is an apple bug which causes weird phantom files to be created whenever an attempt is made to create a file with a leading ".."

As a workaround I figured the simplest thing to do would be to ensure that rsync only ever adds a "." when creating tmp files for filenames that do not already have a leading dot. 

I've attached a modified version of the get_tmpname method which simply wraps the addition of a "." in an if statement. 

I'd like to ask the list if you think this is a likely to have any issues (eg filename comparisons relying on a dot always being added). 

On my system this change seems to work around the problem pretty well. 

Thanks
Ira

( Look for "Modified Code" so see my change )

int get_tmpname(char *fnametmp, const char *fname)
{
	int maxname, added, length = 0;
	const char *f;

	if (tmpdir) {
		/* Note: this can't overflow, so the return value is safe */
		length = strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2);
		fnametmp[length++] = '/';
	}

	if ((f = strrchr(fname, '/')) != NULL) {
		++f;
		if (!tmpdir) {
			length = f - fname;
			/* copy up to and including the slash */
			strlcpy(fnametmp, fname, length + 1);
		}
	} else
		f = fname;
		
	// Modified Code 	
	if ( f[0]!='.'){ 
		fnametmp[length++] = '.';
	} 
	// End Modified Code 
	
	/* The maxname value is bufsize, and includes space for the '\0'.
	 * (Note that NAME_MAX get -8 for the leading '.' above.) */
	maxname = MIN(MAXPATHLEN - 7 - length, NAME_MAX - 8);

	if (maxname < 1) {
		rprintf(FERROR_XFER, "temporary filename too long: %s\n", fname);
		fnametmp[0] = '\0';
		return 0;
	}

	added = strlcpy(fnametmp + length, f, maxname);
	if (added >= maxname)
		added = maxname - 1;
	memcpy(fnametmp + length + added, ".XXXXXX", 8);

	return 1;
}


More information about the rsync mailing list