On Tue, Mar 11, 2003 at 10:47:10AM +0100, Paul Slootman wrote: > On Tue 11 Mar 2003, jw schultz wrote: > > > > That or char fscratch[MAXPATHLEN]; > > Just don't use malloc. > > How about this: > > > static int get_tmpname(char *fnametmp, char *fname) > { > char *f; > char *dir = ""; /* what dir to put the temp file in */ > char namepart[NAME_MAX-10]; /* we never need more than this, if */ > /* the name is longer, we would end */ > /* up having to shorten it anyway */ > if (tmpdir) > dir = tmpdir; > > f = strrchr(fname,'/'); /* is there a directory to skip in fname? */ > if (f == NULL) { /* no */ > /* the strlcpy takes care of making the name short enough */ > /* and null-terminating it at the same time. */ > strlcpy(namepart, fname, sizeof(namepart)); > } > else { /* yes */ > strlcpy(namepart, f+1, sizeof(namepart));
If we aren't using tmpdir we need to strlcpy(dir, fname, f - fname) at which point we've just copied all of fname anyway. > } > > if (strlen(dir)+strlen(namepart)+1 > MAXPATHLEN) { > /* how often will this happen... the temp dir would have to */ > /* a very long name, and hence the fault of the user who */ > /* specified it. Let him fix the problem. */ > rprintf(FERROR,"filename too long\n"); > return 0; > } > > /* construct temp name template */ > snprintf(fnametmp, MAXPATHLEN, "%s%s.%s.XXXXXX", > dir, dir[0]?"/":"", namepart); Please use whitespace in the ?: > > return 1; > } > > > Even shorter than it was, it should now be difficult to mess this up :-) > I thought of letting the default value of dir be "./", but then > clean_fname would end up shifting that off again, thus wasting > resources. I'd say it was better to copy fname and mangle the copy. The alternative is to make the dir array MAXPATHLEN long. Should also add to rsync.h #ifndef NAME_MAX #define NAME_MAX 255 #endif Just in case. Hmm. I'm thinking we should just build fnametmp a piece at a time. I coded it up to see how it would look. Not as intuitive but there is a lot less strlen and no snprintf. It also deals shortens the filename both for MAXPATHLEN and for NAME_MAX so it is almost impossible for the function to fail or produce a pathname that breaks things. The only more surefire way to not make a bad tempfile name would be to always make maxname = max(strlen(f) < 10, 0) static int get_tmpname(char *fnametmp, char *fname) { char *f; int length = 0; int maxname; if (tmpdir) { strlcpy(fnametmp, tmpdir, MAXPATHLEN - 2); length = strlen(fnametmp); } if (f = strrchr(fname, '/')) { if (!tmpdir) { length = f - fname; strlcpy(fnametmp, fname, length); } ++f; } else { f = fname; } strcpy(fnametmp + length, "/."); length += 2; maxname = MIN(MAXPATHLEN - 8 - length, NAME_MAX - 9); if (maxname < 1) { rprintf(FERROR, "temporary filename too long: %s\n", fname); return 0; } strlcpy(fnametmp + length, f, maxname); strcat(fnametmp + length, ".XXXXXX"); return 1; } -- ________________________________________________________________ J.W. Schultz Pegasystems Technologies email address: [EMAIL PROTECTED] Remember Cernan and Schmitt -- To unsubscribe or change options: http://lists.samba.org/mailman/listinfo/rsync Before posting, read: http://www.tuxedo.org/~esr/faqs/smart-questions.html