summaryrefslogtreecommitdiffstats
path: root/contrib/cvs/src/checkout.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/cvs/src/checkout.c')
-rw-r--r--contrib/cvs/src/checkout.c103
1 files changed, 66 insertions, 37 deletions
diff --git a/contrib/cvs/src/checkout.c b/contrib/cvs/src/checkout.c
index 46151eb..c6a8122 100644
--- a/contrib/cvs/src/checkout.c
+++ b/contrib/cvs/src/checkout.c
@@ -242,6 +242,13 @@ checkout (argc, argv)
error (1, 0, "tag `%s' must be a symbolic tag", tag);
}
+#ifdef SERVER_SUPPORT
+ if (server_active && where != NULL)
+ {
+ server_pathname_check (where);
+ }
+#endif
+
if (!safe_location()) {
error(1, 0, "Cannot check out files into the repository itself");
}
@@ -428,11 +435,15 @@ struct dir_to_build
/* The path to the directory. */
char *dirpath;
+ /* If set, don't build the directory, just change to it.
+ The caller will also want to set REPOSITORY to NULL. */
+ int just_chdir;
+
struct dir_to_build *next;
};
static int build_dirs_and_chdir PROTO ((struct dir_to_build *list,
- int sticky, int check_existing_dirs));
+ int sticky));
static void build_one_dir PROTO ((char *, char *, int));
@@ -723,6 +734,7 @@ internal error: %s doesn't start with %s in checkout_proc",
head->repository = NULL;
head->dirpath = xstrdup (where);
head->next = NULL;
+ head->just_chdir = 0;
/* Make a copy of the repository name to play with. */
@@ -760,7 +772,26 @@ internal error: %s doesn't start with %s in checkout_proc",
assert (strlen (where));
strcpy (new->dirpath, "/");
}
-
+ new->next = head;
+ head = new;
+
+ /* If where consists of multiple pathname components,
+ then we want to just cd into it, without creating
+ directories or modifying CVS directories as we go.
+ In CVS 1.9 and earlier, the code actually does a
+ CVS_CHDIR up-front; I'm not going to try to go back
+ to that exact code but this is somewhat similar
+ in spirit. */
+ if (where_orig != NULL
+ && cp - where < strlen (where_orig))
+ {
+ new->repository = NULL;
+ new->just_chdir = 1;
+ continue;
+ }
+
+ new->just_chdir = 0;
+
/* Now figure out what repository directory to generate.
The most complete case would be something like this:
@@ -771,12 +802,13 @@ internal error: %s doesn't start with %s in checkout_proc",
cvs co -d what/ever -N foo
The results in the CVS/Repository files should be:
- . -> . (this is where we executed the cmd)
- what -> Emptydir (generated dir -- not in repos)
+ . -> (don't touch CVS/Repository)
+ (I think this case might be buggy currently)
+ what -> (don't touch CVS/Repository)
ever -> . (same as "cd what/ever; cvs co -N foo")
bar -> Emptydir (generated dir -- not in repos)
baz -> quux (finally!) */
-
+
if (strcmp (reposcopy, CVSroot_directory) == 0)
{
/* We can't walk up past CVSROOT. Instead, the
@@ -835,9 +867,6 @@ internal error: %s doesn't start with %s in checkout_proc",
}
}
}
-
- new->next = head;
- head = new;
}
/* clean up */
@@ -852,12 +881,29 @@ internal error: %s doesn't start with %s in checkout_proc",
may not have a thing to do with where the sources are
being checked out. If it does, build_dirs_and_chdir
will take care of creating adm files here. */
-
- if (! where_is_absolute)
+ /* FIXME: checking where_is_absolute is a horrid kludge;
+ I suspect we probably can just skip the call to
+ build_one_dir whenever the -d command option was specified
+ to checkout. */
+
+ if (! where_is_absolute && top_level_admin)
{
/* It may be argued that we shouldn't set any sticky
bits for the top-level repository. FIXME? */
build_one_dir (CVSroot_directory, ".", *pargc <= 1);
+
+#ifdef SERVER_SUPPORT
+ /* We _always_ want to have a top-level admin
+ directory. If we're running in client/server mode,
+ send a "Clear-static-directory" command to make
+ sure it is created on the client side. (See 5.10
+ in cvsclient.dvi to convince yourself that this is
+ OK.) If this is a duplicate command being sent, it
+ will be ignored on the client side. */
+
+ if (server_active)
+ server_clear_entstat (".", CVSroot_directory);
+#endif
}
@@ -866,8 +912,7 @@ internal error: %s doesn't start with %s in checkout_proc",
contain a CVS subdir yet, but all the others contain
CVS and Entries.Static files */
- if (build_dirs_and_chdir (head, *pargc <= 1,
- where_is_absolute) != 0)
+ if (build_dirs_and_chdir (head, *pargc <= 1) != 0)
{
error (0, 0, "ignoring module %s", omodule);
err = 1;
@@ -1101,22 +1146,13 @@ emptydir_name ()
return repository;
}
-
-/* Build all the dirs along the path to DIRS with CVS subdirs with
- appropriate repositories. If ->repository is NULL, do not create a
- CVSADM directory for that subdirectory; just CVS_CHDIR into it. If
- check_existing_dirs is nonzero, don't create directories if they
- already exist, and don't try to write adm files in directories
- where we don't have write permission. We use this last option
- primarily when a user has specified an absolute path for checkout
- -- we will often not have permission to top-level directories, so
- we shouldn't complain. */
-
+/* Build all the dirs along the path to DIRS with CVS subdirs with appropriate
+ repositories. If ->repository is NULL, do not create a CVSADM directory
+ for that subdirectory; just CVS_CHDIR into it. */
static int
-build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
+build_dirs_and_chdir (dirs, sticky)
struct dir_to_build *dirs;
int sticky;
- int check_existing_dirs;
{
int retval = 0;
struct dir_to_build *nextdir;
@@ -1124,16 +1160,12 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
while (dirs != NULL)
{
char *dir = last_component (dirs->dirpath);
- int dir_is_writeable;
- if ((! check_existing_dirs) || (! isdir (dir)))
+ if (!dirs->just_chdir)
+ {
mkdir_if_needed (dir);
-
- Subdir_Register (NULL, NULL, dir);
-
- /* This is an expensive call -- only make it if necessary. */
- if (check_existing_dirs)
- dir_is_writeable = iswritable (dir);
+ Subdir_Register (NULL, NULL, dir);
+ }
if (CVS_CHDIR (dir) < 0)
{
@@ -1141,14 +1173,11 @@ build_dirs_and_chdir (dirs, sticky, check_existing_dirs)
retval = 1;
goto out;
}
-
- if ((dirs->repository != NULL)
- && ((! check_existing_dirs) || dir_is_writeable))
+ if (dirs->repository != NULL)
{
build_one_dir (dirs->repository, dirs->dirpath, sticky);
free (dirs->repository);
}
-
nextdir = dirs->next;
free (dirs->dirpath);
free (dirs);
OpenPOWER on IntegriCloud