bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

(no subject)


From: christos
Subject: (no subject)
Date: Mon, 22 Apr 2002 11:11:29 -0400 (EDT)

>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 
kim@nix.gw.com:/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;
 }
 
 /*



reply via email to

[Prev in Thread] Current Thread [Next in Thread]