hi, all. I had an problem with rsync-2.5.4/5 related to filename length. On Linux box (kernel-2.4.18 + ext3 fs), filename length limits to 255byte, but rsync can't handle fn > (255 -9) byte. So I had an instant hack to avoid this problem. Patch file attatched works fine in my case, but I'm not sure that it is correct or not. Any suggestions ? Please cc me, I'm not on this list. Regards, Hiroshi -------------- next part -------------- diff -urN rsync-2.5.5.orig/receiver.c rsync-2.5.5/receiver.c --- rsync-2.5.5.orig/receiver.c Thu Feb 14 03:41:58 2002 +++ rsync-2.5.5/receiver.c Sat Jun 8 03:41:22 2002 @@ -163,10 +163,16 @@ } } +#include <sys/vfs.h> +static inline int fname_syslimit(const char* path) { + struct statfs sb; + return !statfs(path,&sb) ? sb.f_namelen : 255; +} static int get_tmpname(char *fnametmp, char *fname) { char *f; + int fn_max; /* open tmp file */ if (tmpdir) { @@ -179,7 +185,12 @@ rprintf(FERROR,"filename too long\n"); return 0; } - snprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f); + fn_max = fname_syslimit(tmpdir); + if(strlen(f)+9 > fn_max) { + snprintf(fnametmp,MAXPATHLEN, "%s/%s",tmpdir,f); + strncpy(fnametmp + strlen(fnametmp) - 6,"XXXXXX",6); + }else + snprintf(fnametmp,MAXPATHLEN, "%s/.%s.XXXXXX",tmpdir,f); return 1; } @@ -190,13 +201,23 @@ return 0; } + fn_max = fname_syslimit(fname); + if (f) { *f = 0; - snprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX", - fname,f+1); + if(strlen(f+1)+9 > fn_max) { + snprintf(fnametmp,MAXPATHLEN, "%s/%s",fname,f + 1); + strncpy(fnametmp + strlen(fnametmp) - 6,"XXXXXX",6); + }else + snprintf(fnametmp,MAXPATHLEN,"%s/.%s.XXXXXX", + fname,f+1); *f = '/'; } else { - snprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname); + if(strlen(fname)+9 > fn_max) { + snprintf(fnametmp,MAXPATHLEN, "%s",fname); + strncpy(fnametmp + strlen(fnametmp) - 6,"XXXXXX",6); + }else + snprintf(fnametmp,MAXPATHLEN,".%s.XXXXXX",fname); } return 1; @@ -408,21 +429,33 @@ buf = NULL; } - if (!get_tmpname(fnametmp,fname)) { - if (buf) unmap_file(buf); - if (fd1 != -1) close(fd1); - continue; + { + static const int max_retry = 10; + int retry = 0; + int flag = 0; + + do { + if (!get_tmpname(fnametmp,fname)) { + if (buf) unmap_file(buf); + if (fd1 != -1) close(fd1); + flag = 1; + break; + } + + strlcpy(template, fnametmp, sizeof(template)); + + /* we initially set the perms without the + setuid/setgid bits to ensure that there is no race + condition. They are then correctly updated after + the lchown. Thanks to snabb@epipe.fi for pointing + this out. We also set it initially without group + access because of a similar race condition. */ + + fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); + }while(!flag && (retry++ < max_retry) && + (fd2 == -1 && errno == EEXIST)); + if(flag) continue; } - - strlcpy(template, fnametmp, sizeof(template)); - - /* we initially set the perms without the - setuid/setgid bits to ensure that there is no race - condition. They are then correctly updated after - the lchown. Thanks to snabb@epipe.fi for pointing - this out. We also set it initially without group - access because of a similar race condition. */ - fd2 = do_mkstemp(fnametmp, file->mode & INITACCESSPERMS); if (fd2 == -1) { rprintf(FERROR,"mkstemp %s failed: %s\n",fnametmp,strerror(errno)); receive_data(f_in,buf,-1,NULL,file->length);