>Submitter-Id: net >Originator: Christos Zoulas >Organization: None, but trying. >Confidential: no >Synopsis: cvs gets confused about with symlinked root directory when cvslock dir >is present >Severity: serious >Priority: medium >Category: 1.11.2 >Class: sw-bug >Release: cvs-1.11.2 >Environment: System: NetBSD beowulf.gw.com 1.5ZC NetBSD 1.5ZC (GW-GENERIC) #46: Tue Apr 9 13:45:13 EDT 2002 [EMAIL PROTECTED]:/net/beowulf/src-1/NetBSD/cvsroot/src/sys/arch/i386/compile/GW-GENERIC i386
>Description: cvs gets confused with symlinks and cvs root directories that are accessed via symlinks, when we specify a cvs lock directory. >How-To-Repeat: 1. set cvs to use a separate locks tree, eg. /tmp/cvslock 2. setup your cvs repository via amd or just /foo/bar/baz 3. ln -s /foo/bar/baz /cvsroot 4. try cvs -d mymachine:/cvsroot checkout -jfoo:yestarday -jfoo modblah Notice the assertion failing on lock.c because the repository is /foo/bar/baz/mymodule... and parsed_root is /cvsroot >Fix: Index: lock.c =================================================================== RCS file: /src/twosigma/cvsroot/pub/devel/cvs/src/lock.c,v retrieving revision 1.3 diff -u -u -r1.3 lock.c --- lock.c 22 Apr 2002 14:20:57 -0000 1.3 +++ lock.c 22 Apr 2002 14:56:52 -0000 @@ -97,6 +97,7 @@ static void set_lockers_name PROTO((struct stat *statp)); static int set_writelock_proc PROTO((Node * p, void *closure)); static int unlock_proc PROTO((Node * p, void *closure)); +static int find_root PROTO((char *repository, char *rootdir)); static int write_lock PROTO ((struct lock *lock)); static void lock_simple_remove PROTO ((struct lock *lock)); static void lock_wait PROTO((char *repository)); @@ -169,14 +170,19 @@ { struct stat sb; mode_t new_mode = 0; + int len; /* The interesting part of the repository is the part relative to CVSROOT. */ assert (current_parsed_root != NULL); assert (current_parsed_root->directory != NULL); - assert (strncmp (repository, current_parsed_root->directory, - strlen (current_parsed_root->directory)) == 0); - short_repos = repository + strlen (current_parsed_root->directory) + 1; + /* + * Unfortunately, string comparisons are not enough because we + * might have symlinks present + */ + len = find_root(repository, current_parsed_root->directory); + assert(len != -1); + short_repos = repository + len + 1; if (strcmp (repository, current_parsed_root->directory) == 0) short_repos = "."; @@ -277,6 +283,45 @@ } } return retval; +} + +/* + * Find the root directory in the repository director + */ +static int +find_root(repository, rootdir) + char *repository; + char *rootdir; +{ + struct stat strep, stroot; + char *p = NULL, *q = NULL; + size_t len; + + if (stat(rootdir, &stroot) == -1) + return -1; + len = strlen(repository); + do { + if (p != NULL) { + len = p - repository; + *p = '\0'; + } + if (q != NULL) + *q = '/'; + if (stat(repository, &strep) == -1) { + if (p != NULL) + *p = '/'; + return -1; + } + if (strep.st_dev == stroot.st_dev && strep.st_ino == stroot.st_ino) { + if (p != NULL) + *p = '/'; + if (q != NULL) + *q = '/'; + return len; + } + q = p; + } while ((p = strrchr(repository, '/')) != NULL); + return -1; } /* _______________________________________________ Bug-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-cvs