bug-cvs
[Top][All Lists]
Advanced

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

cvs has problems using LockDir when CVSROOT holds a symlink


From: Mark D. Baushke
Subject: cvs has problems using LockDir when CVSROOT holds a symlink
Date: Mon, 22 Sep 2003 23:58:53 -0700

Greetings,

Consider the following situation.

 1) /path/to/cvs/repository is the path to a repository.

 2) /path/to/cvs/repository/CVSROOT/config contains a 
    "LockDir=/var/cvs-locks/repository" directive and the 
    /var/cvs-locks/repository directory exists with reasonable
    permissons to allow checkout of the tree.

 3) /cvs/repository is a symbolic link to the /path/to/cvs/repository
    directory.

A user is able to use:

  cvs -d host:/cvs/repository checkout CVSROOT

(or any other module) with no problems. However, the r* commands
(rlog, rdiff, etc) such as:

  cvs -d host:/cvs/repository rlog -r1.1 CVSROOT/config

yields up a problem:

assertion "strncmp (repository, current_parsed_root->directory, strlen 
(current_parsed_root->directory)) == 0" failed: file "lock.c", line 187
cvs [server aborted]: received abort signal
assertion "strncmp (repository, current_parsed_root->directory, strlen 
(current_parsed_root->directory)) == 0" failed: file "lock.c", line 187
cvs [server aborted]: received abort signal

which is in the src/lock.c::lock_name() function and looks like this:

      assert (strncmp (repository, current_parsed_root->directory,
                       strlen (current_parsed_root->directory)) == 0);

the value of repository is "/path/to/cvs/repository/CVSROOT" and the
value of current_parsed_root->directory is "/cvs/repository" at the
time of the assertion failure.

The fix would seem to be to use xreadlink() on the
current_parsed_root->directory in the case that the repository variable
is not a superset of it.

What follows is a patch that allows the rdiff and rlog commands to work.

Does anyone see any problems with this patch or have any comments about
it?

        Thanks,
        -- Mark

Log message:

* lock.c (lock_name): Work around possible symbolic links in the
current_parsed_root->directory when using LockDir.

* sanity.sh (Server): New test for LockDir config item with and
without CVSROOT using a symbolic link directory.

--- src/lock.c.~1.59.4.2.~      Wed Jul 30 11:40:49 2003
+++ src/lock.c  Mon Sep 22 15:20:18 2003
@@ -179,19 +179,43 @@ lock_name (repository, name)
     {
        struct stat sb;
        mode_t new_mode = 0;
+       size_t parsed_root_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;
+       parsed_root_len = strlen (current_parsed_root->directory);
+       if (strncmp (repository, current_parsed_root->directory,
+                    parsed_root_len) == 0)
+       {
+           short_repos = repository + parsed_root_len + 1;
 
-       if (strcmp (repository, current_parsed_root->directory) == 0)
-           short_repos = ".";
+           if (strcmp (repository, current_parsed_root->directory) == 0)
+               short_repos = ".";
+           else
+               assert (short_repos[-1] == '/');
+       }
        else
-           assert (short_repos[-1] == '/');
+       {
+           /* Some part of the current_parsed_root->directory may
+              be a symbolic link. */
+           char *root = xreadlink(current_parsed_root->directory);
+           size_t root_len = strlen (root);
+           if (strncmp (repository, root, root_len) == 0)
+           {
+               short_repos = repository + root_len + 1;
+
+               if (strcmp (repository, root) == 0)
+                   short_repos = ".";
+               else
+                   assert (short_repos[-1] == '/');
+           }
+           else
+               assert (strncmp (repository, current_parsed_root->directory,
+                                parsed_root_len) == 0);
+           free (root);
+       }
 
        retval = xmalloc (strlen (lock_dir)
                          + strlen (short_repos)
--- src/sanity.sh.~1.752.2.39.~ Mon Sep 22 13:43:49 2003
+++ src/sanity.sh       Mon Sep 22 18:38:03 2003
@@ -747,7 +747,7 @@ if test x"$*" = x; then
        tests="${tests} serverpatch log log2 logopt ann ann-id"
        # Repository Storage (RCS file format, CVS lock files, creating
        # a repository without "cvs init", &c).
-       tests="${tests} crerepos rcs rcs2 rcs3 lockfiles backuprecover"
+       tests="${tests} crerepos rcs rcs2 rcs3 lockfiles lockdir backuprecover"
        # More history browsing, &c.
        tests="${tests} history"
        tests="${tests} big modes modes2 modes3 stamps"
@@ -18454,6 +18454,99 @@ ${PROG} commit: Rebuilding administrativ
          rm -rf ${CVSROOT_DIRNAME}/first-dir
          ;;
 
+       lockdir)
+         # Tests that the full range of commands does the right
+         # thing with regard to LockDir directives.
+         mkdir lockdir; cd lockdir
+
+         dotest lockdir-1 "${testcvs} -Q co CVSROOT" ""
+         cd CVSROOT
+         echo "LockDir=${TESTDIR}/locks" >config
+         dotest lockdir-2 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+         dotest_fail lockdir-3 "${testcvs} rlog -r1.1 CVSROOT/config" \
+"${PROG} .rlog aborted.: cannot stat ${TESTDIR}/locks: No such file or 
directory
+${PROG} .rlog aborted.: cannot stat ${TESTDIR}/locks: No such file or 
directory"
+         dotest lockdir-4 "mkdir ${TESTDIR}/locks" ""
+         dotest lockdir-5 "${testcvs} rlog -r1.1 CVSROOT/config" \
+"
+RCS file: ${CVSROOT_DIRNAME}/CVSROOT/config,v
+head: 1\.[0-9]*
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: [0-9]*;       selected revisions: 1
+description:
+----------------------------
+revision 1.1
+date: [0-9/]* [0-9:]*;  author: $username;  state: Exp;
+.*
+============================================================================="
+
+         dotest lockdir-6 "ln -s ${CVSROOT_DIRNAME} ${TESTDIR}/symlink" ""
+          if $remote; then
+           dotest lockdir-7r \
+"${testcvs} -d :fork:${TESTDIR}/symlink rlog -r1.1 CVSROOT/config" \
+"
+RCS file: ${CVSROOT_DIRNAME}/CVSROOT/config,v
+head: 1\.[0-9]*
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: [0-9]*;       selected revisions: 1
+description:
+----------------------------
+revision 1.1
+date: [0-9/]* [0-9:]*;  author: $username;  state: Exp;
+.*
+============================================================================="
+          else
+           dotest lockdir-7 \
+"${testcvs} -d ${TESTDIR}/symlink rlog -r1.1 CVSROOT/config" \
+"
+RCS file: ${CVSROOT_DIRNAME}/CVSROOT/config,v
+head: 1\.[0-9]*
+branch:
+locks: strict
+access list:
+symbolic names:
+keyword substitution: kv
+total revisions: [0-9]*;       selected revisions: 1
+description:
+----------------------------
+revision 1.1
+date: [0-9/]* [0-9:]*;  author: $username;  state: Exp;
+.*
+============================================================================="
+          fi
+       
+         echo "# nobody here but us comments" >config
+         dotest lockdir-cleanup-1 "${testcvs} -q ci -m config-it" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+
+         cd ../..
+
+         if $keep; then
+           echo Keeping ${TESTDIR} and exiting due to --keep
+           exit 0
+         fi
+
+         rm -fr lockdir ${TESTDIR}/locks         
+         rm -f ${TESTDIR}/symlink
+         ;;
+
        backuprecover)
          # Tests to make sure we get the expected behavior
          # when we recover a repository from an old backup




reply via email to

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