summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2005-12-04 17:32:45 +0000
committerJoris Vink <joris@cvs.openbsd.org>2005-12-04 17:32:45 +0000
commitc2c15e14eafea2b809b1b86011124ce5969a5698 (patch)
tree200570a5ca76dc1279f6d6ea0c3627830af1ea01
parent8725bd0621d927b5c94792b68fe2660400146d71 (diff)
bye obsolete junk;
"go ahead" and "nuke them" niallo@, xsa@
-rw-r--r--usr.bin/cvs/repo.c648
-rw-r--r--usr.bin/cvs/repo.h155
2 files changed, 0 insertions, 803 deletions
diff --git a/usr.bin/cvs/repo.c b/usr.bin/cvs/repo.c
deleted file mode 100644
index a68c90dd9c5..00000000000
--- a/usr.bin/cvs/repo.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/* $OpenBSD: repo.c,v 1.10 2005/11/28 08:49:25 xsa Exp $ */
-/*
- * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "log.h"
-#include "repo.h"
-
-
-
-static CVSRPENT *cvs_repo_loadrec(CVSREPO *, const char *);
-
-
-/*
- * cvs_repo_load()
- *
- * Load the information for a specific CVS repository whose base directory
- * is specified in <base>.
- */
-
-CVSREPO *
-cvs_repo_load(const char *base, int flags)
-{
- struct stat st;
- CVSREPO *repo;
-
- cvs_log(LP_DEBUG, "loading repository %s", base);
-
- if (stat(base, &st) == -1) {
- cvs_log(LP_ERRNO, "failed to stat `%s'", base);
- return (NULL);
- }
-
- if (!S_ISDIR(st.st_mode)) {
- cvs_log(LP_ERR, "%s: repository path is not a directory", base);
- return (NULL);
- }
-
- repo = (struct cvs_repo *)malloc(sizeof(*repo));
- if (repo == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate repository data");
- return (NULL);
- }
- memset(repo, 0, sizeof(*repo));
-
- TAILQ_INIT(&(repo->cr_modules));
-
- repo->cr_path = strdup(base);
- if (repo->cr_path == NULL) {
- cvs_log(LP_ERRNO, "failed to copy repository path");
- free(repo);
- return (NULL);
- }
-
- repo->cr_tree = cvs_repo_loadrec(repo, repo->cr_path);
- if (repo->cr_tree == NULL) {
- cvs_repo_free(repo);
- return (NULL);
- }
-
- return (repo);
-}
-
-
-/*
- * cvs_repo_free()
- *
- * Free the data associated to a repository.
- */
-
-void
-cvs_repo_free(CVSREPO *repo)
-{
- CVSMODULE *mod;
-
- if (repo != NULL) {
- if (repo->cr_path != NULL)
- free(repo->cr_path);
-
- while ((mod = TAILQ_FIRST(&(repo->cr_modules))) != NULL) {
- TAILQ_REMOVE(&(repo->cr_modules), mod, cm_link);
- cvs_repo_modfree(mod);
- }
-
- if (repo->cr_tree != NULL)
- cvs_repo_entfree(repo->cr_tree);
-
- free(repo);
- }
-}
-
-
-/*
- * cvs_repo_lockdir()
- *
- * Obtain a lock on the directory <dir> which is relative to the root of
- * the repository <repo>. The owner of the lock becomes <pid>.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_lockdir(CVSREPO *repo, const char *dir, int type, pid_t owner)
-{
- CVSRPENT *ent;
-
- if ((ent = cvs_repo_find(repo, dir)) == NULL) {
- return (-1);
- }
-
- return cvs_repo_lockent(ent, type, owner);
-}
-
-
-/*
- * cvs_repo_unlockdir()
- *
- * Attempt to unlock the directory <dir> in the repository <repo>. The <owner>
- * argument is used to make sure that the caller really owns the lock it is
- * trying to release.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_unlockdir(CVSREPO *repo, const char *dir, pid_t owner)
-{
- CVSRPENT *ent;
-
- if ((ent = cvs_repo_find(repo, dir)) == NULL) {
- return (-1);
- }
-
- return cvs_repo_unlockent(ent, owner);
-}
-
-
-/*
- * cvs_repo_lockent()
- *
- * Obtain a lock on the entry <ent>. The owner of the lock becomes <pid>.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_lockent(CVSRPENT *ent, int type, pid_t owner)
-{
- struct cvs_lock *lk;
- struct cvs_lklist *list;
-
- if ((type != CVS_LOCK_READ) && (type != CVS_LOCK_WRITE)) {
- cvs_log(LP_ERR, "invalid lock type (%d) requested");
- return (-1);
- }
-
- lk = (struct cvs_lock *)malloc(sizeof(*lk));
- if (lk == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate repository lock");
- return (-1);
- }
- lk->lk_owner = owner;
- lk->lk_type = type;
- lk->lk_ent = ent;
-
- if ((ent->cr_wlock != NULL) && (ent->cr_wlock->lk_owner != 0)) {
- /*
- * Another process has already locked the entry with a write
- * lock, so regardless of the type of lock we are requesting,
- * we'll have to wait in the pending requests queue.
- */
- if (ent->cr_wlock->lk_owner == owner) {
- cvs_log(LP_WARN, "double-lock attempt");
- free(lk);
- } else
- TAILQ_INSERT_TAIL(&(ent->cr_lkreq), lk, lk_link);
- } else {
- if (type == CVS_LOCK_READ) {
- /*
- * If there are any pending write lock requests,
- * add the read lock request at the tail of the queue
- * instead of assigning it right away. Otherwise,
- * we could end up with a write lock request never
- * being obtained if other processes make overlapping
- * read lock requests.
- */
- if (TAILQ_EMPTY(&(ent->cr_lkreq)))
- list = &(ent->cr_rlocks);
- else
- list = &(ent->cr_lkreq);
- TAILQ_INSERT_TAIL(list, lk, lk_link);
- } else if (type == CVS_LOCK_WRITE) {
- if (TAILQ_EMPTY(&(ent->cr_rlocks)))
- ent->cr_wlock = lk;
- else
- TAILQ_INSERT_TAIL(&(ent->cr_lkreq),
- lk, lk_link);
- }
- }
-
- return (0);
-}
-
-
-/*
- * cvs_repo_unlockent()
- *
- * Attempt to unlock the entry <ent>. The <owner> argument is used to make
- * sure that the caller really owns the lock it is trying to release.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_unlockent(CVSRPENT *ent, pid_t owner)
-{
- struct cvs_lock *lk;
-
- if ((ent->cr_wlock != NULL) && (ent->cr_wlock->lk_owner != 0)) {
- if (ent->cr_wlock->lk_owner != owner) {
- cvs_log(LP_ERR, "child %d attempted to unlock write "
- "lock owned by %d", ent->cr_wlock->lk_owner);
- return (-1);
- }
-
- free(ent->cr_wlock);
- ent->cr_wlock = NULL;
- } else {
- TAILQ_FOREACH(lk, &(ent->cr_rlocks), lk_link) {
- if (lk->lk_owner == owner) {
- TAILQ_REMOVE(&(ent->cr_rlocks), lk, lk_link);
- free(lk);
- break;
- }
- }
- }
-
-#ifdef notyet
- /* assign lock to any process with a pending request */
- while ((lk = TAILQ_FIRST(&(ent->cr_lkreq))) != NULL) {
- TAILQ_REMOVE(&(ent->cr_lkreq), lk, lk_link);
- /* XXX send message to process */
- child = cvsd_child_find(lk->lk_owner);
- if (child == NULL)
- continue;
-
- break;
- }
-#endif
-
- return (0);
-}
-
-
-/*
- * cvs_repo_alias()
- *
- * Add a new module entry with name <alias> in the repository <repo>, which
- * points to the path <path> within the repository.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_alias(CVSREPO *repo, const char *path, const char *alias)
-{
- CVSMODULE *mod;
-
- mod = (CVSMODULE *)malloc(sizeof(*mod));
- if (mod == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate module alias");
- return (-1);
- }
- memset(mod, 0, sizeof(*mod));
-
- mod->cm_name = strdup(alias);
- if (mod->cm_name == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate module alias");
- free(mod);
- return (-1);
- }
- mod->cm_flags |= CVS_MODULE_ISALIAS;
-
- mod->cm_path = strdup(path);
- if (mod->cm_path == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate module alias");
- free(mod->cm_name);
- free(mod);
- return (-1);
- }
-
- TAILQ_INSERT_TAIL(&(repo->cr_modules), mod, cm_link);
-
- return (0);
-}
-
-
-/*
- * cvs_repo_unalias()
- *
- * Remove the module alias <alias> from the repository <repo>.
- * Returns 0 on success, or -1 on failure.
- */
-int
-cvs_repo_unalias(CVSREPO *repo, const char *alias)
-{
- CVSMODULE *mod;
-
- TAILQ_FOREACH(mod, &(repo->cr_modules), cm_link) {
- if (strcmp(mod->cm_name, alias) == 0) {
- if (!(mod->cm_flags & CVS_MODULE_ISALIAS)) {
- cvs_log(LP_ERR,
- "attempt to remove non-aliased module `%s'",
- mod->cm_name);
- return (-1);
- }
-
- break;
- }
- }
- if (mod == NULL)
- return (-1);
-
- TAILQ_REMOVE(&(repo->cr_modules), mod, cm_link);
- return (0);
-}
-
-
-/*
- * cvs_repo_find()
- *
- * Find the pointer to a CVS file entry within the file hierarchy <hier>.
- * The file's pathname <path> must be relative to the base of <hier>.
- * Returns the entry on success, or NULL on failure.
- */
-CVSRPENT*
-cvs_repo_find(CVSREPO *repo, const char *path)
-{
- size_t len;
- char *pp, *sp, pbuf[MAXPATHLEN];
- CVSRPENT *sf, *cf;
-
- if ((len = strlcpy(pbuf, path, sizeof(pbuf))) >= sizeof(pbuf)) {
- errno = ENAMETOOLONG;
- cvs_log(LP_ERRNO, "%s", path);
- return (NULL);
- }
-
- /* remove any trailing slashes */
- while ((len > 0) && (pbuf[len - 1] == '/'))
- pbuf[--len] = '\0';
-
- cf = repo->cr_tree;
- pp = pbuf;
- do {
- if (cf->cr_type != CVS_RPENT_DIR) {
- errno = ENOTDIR;
- cvs_log(LP_ERRNO, "%s", path);
- return (NULL);
- }
- sp = strchr(pp, '/');
- if (sp != NULL)
- *(sp++) = '\0';
-
- /* special case */
- if (*pp == '.') {
- if ((*(pp + 1) == '.') && (*(pp + 2) == '\0')) {
- /* request to go back to parent */
- if (cf->cr_parent == NULL) {
- cvs_log(LP_NOTICE,
- "path %s goes back too far", path);
- return (NULL);
- }
- cf = cf->cr_parent;
- continue;
- } else if (*(pp + 1) == '\0')
- continue;
- }
-
- TAILQ_FOREACH(sf, &(cf->cr_files), cr_link) {
- if (strcmp(pp, sf->cr_name) == 0)
- break;
- }
- if (sf == NULL)
- return (NULL);
-
- cf = sf;
- pp = sp;
- } while (sp != NULL);
-
- return (cf);
-}
-
-
-#if 0
-/*
- * cvs_repo_getpath()
- *
- * Get the full path of the file <file> and store it in <buf>, which is of
- * size <len>. For portability, it is recommended that <buf> always be
- * at least MAXPATHLEN bytes long.
- * Returns a pointer to the start of the path on success, or NULL on failure.
- */
-char *
-cvs_repo_getpath(CVSRPENT *file, char *buf, size_t len)
-{
- u_int i;
- char *fp, *namevec[CVS_FILE_MAXDEPTH];
- CVSRPENT *top;
-
- buf[0] = '\0';
- i = CVS_FILE_MAXDEPTH;
- memset(namevec, 0, sizeof(namevec));
-
- /* find the top node */
- for (top = file; (top != NULL) && (i > 0); top = top->cr_parent) {
- fp = top->cr_name;
-
- /* skip self-references */
- if ((fp[0] == '.') && (fp[1] == '\0'))
- continue;
- namevec[--i] = fp;
- }
-
- if (i == 0)
- return (NULL);
- else if (i == CVS_FILE_MAXDEPTH) {
- strlcpy(buf, ".", len);
- return (buf);
- }
-
- while (i < CVS_FILE_MAXDEPTH - 1) {
- strlcat(buf, namevec[i++], len);
- strlcat(buf, "/", len);
- }
- strlcat(buf, namevec[i], len);
-
- return (buf);
-}
-#endif
-
-
-/*
- * cvs_repo_loadrec()
- *
- * Recursively load the repository structure
- */
-static CVSRPENT*
-cvs_repo_loadrec(CVSREPO *repo, const char *path)
-{
- int ret, fd, l;
- long base;
- u_char *dp, *ep;
- mode_t fmode;
- char fbuf[2048], pbuf[MAXPATHLEN];
- struct dirent *ent;
- CVSRPENT *cfp, *cr_ent;
- struct stat st;
-
- cvs_log(LP_NOTICE, "loading %s", path);
- if (stat(path, &st) == -1) {
- cvs_log(LP_ERRNO, "failed to stat `%s'", path);
- return (NULL);
- }
-
- cfp = (CVSRPENT *)malloc(sizeof(*cfp));
- if (cfp == NULL) {
- cvs_log(LP_ERRNO, "failed to allocate repository entry");
- return (NULL);
- }
- memset(cfp, 0, sizeof(*cfp));
- TAILQ_INIT(&(cfp->cr_rlocks));
- TAILQ_INIT(&(cfp->cr_lkreq));
-
- cfp->cr_name = strdup(basename(path));
- if (cfp->cr_name == NULL) {
- cvs_log(LP_ERRNO, "failed to copy entry name");
- free(cfp);
- return (NULL);
- }
-
- if (repo->cr_flags & CVS_REPO_CHKPERM) {
- if (S_ISDIR(st.st_mode))
- fmode = CVSD_DPERM;
- else
- fmode = CVSD_FPERM;
- /* perform permission checks on the file */
- if (st.st_uid != cvsd_uid) {
- cvs_log(LP_WARN, "owner of `%s' is not %s",
- path, CVSD_USER);
- }
-
- if (st.st_gid != cvsd_gid) {
- cvs_log(LP_WARN, "group of `%s' is not %s",
- path, CVSD_GROUP);
- }
-
- if (st.st_mode & S_IWGRP) {
- cvs_log(LP_WARN, "file `%s' is group-writable",
- path, fmode);
- }
-
- if (st.st_mode & S_IWOTH) {
- cvs_log(LP_WARN, "file `%s' is world-writable",
- path, fmode);
- }
- }
-
- if (S_ISREG(st.st_mode))
- cfp->cr_type = CVS_RPENT_RCSFILE;
- else if (S_ISDIR(st.st_mode)) {
- cfp->cr_type = CVS_RPENT_DIR;
-
- TAILQ_INIT(&(cfp->cr_files));
-
- if ((fd = open(path, O_RDONLY)) == -1) {
- cvs_log(LP_ERRNO, "failed to open `%s'", path);
- cvs_repo_entfree(cfp);
- return (NULL);
- }
-
- do {
- ret = getdirentries(fd, fbuf, (int)sizeof(fbuf), &base);
- if (ret == -1) {
- cvs_log(LP_ERRNO,
- "failed to get directory entries");
- cvs_repo_entfree(cfp);
- (void)close(fd);
- return (NULL);
- }
-
- dp = fbuf;
- ep = fbuf + (size_t)ret;
- while (dp < ep) {
- ent = (struct dirent *)dp;
- dp += ent->d_reclen;
- if (ent->d_fileno == 0)
- continue;
-
- if (((ent->d_namlen == 1) &&
- (ent->d_name[0] == '.')) ||
- ((ent->d_namlen == 2) &&
- (ent->d_name[0] == '.') &&
- (ent->d_name[1] == '.')))
- continue;
-
- l = snprintf(pbuf, sizeof(pbuf), "%s/%s", path,
- ent->d_name);
- if (l == -1 || l >= (int)sizeof(pbuf)) {
- errno = ENAMETOOLONG;
- cvs_log(LP_ERRNO, "%s", pbuf);
-
- cvs_repo_entree(cfp);
- (void)close(fd);
- return (NULL);
- }
-
- if ((ent->d_type != DT_DIR) &&
- (ent->d_type != DT_REG)) {
- cvs_log(LP_NOTICE, "skipping non-"
- "regular file `%s'", pbuf);
- continue;
- }
-
- cr_ent = cvs_repo_loadrec(repo, pbuf);
- if (cr_ent == NULL) {
- cvs_repo_entfree(cfp);
- (void)close(fd);
- return (NULL);
- }
-
- cr_ent->cr_parent = cfp;
- TAILQ_INSERT_TAIL(&(cfp->cr_files),
- cr_ent, cr_link);
- }
- } while (ret > 0);
-
- (void)close(fd);
- }
-
- return (cfp);
-}
-
-
-/*
- * cvs_repo_entfree()
- *
- * Free a repository entry structure and all underlying data. In the case of
- * directories, any child entries are also freed recursively.
- */
-void
-cvs_repo_entfree(CVSRPENT *ent)
-{
- CVSRPENT *ch_ent;
-
- if (ent->cr_type == CVS_RPENT_DIR) {
- while ((ch_ent = TAILQ_FIRST(&(ent->cr_files))) != NULL) {
- TAILQ_REMOVE(&(ent->cr_files), ch_ent, cr_link);
- cvs_repo_entfree(ch_ent);
- }
-
- }
-
- if (ent->cr_name != NULL)
- free(ent->cr_name);
- free(ent);
-}
-
-
-/*
- * cvs_repo_modfree()
- *
- * Free a CVS module structure.
- */
-void
-cvs_repo_modfree(CVSMODULE *mod)
-{
- if (mod->cm_name != NULL)
- free(mod->cm_name);
- if (mod->cm_path != NULL)
- free(mod->cm_path);
- free(mod);
-}
diff --git a/usr.bin/cvs/repo.h b/usr.bin/cvs/repo.h
deleted file mode 100644
index 3b92b8af949..00000000000
--- a/usr.bin/cvs/repo.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* $OpenBSD: repo.h,v 1.3 2005/08/08 11:47:53 xsa Exp $ */
-/*
- * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef REPO_H
-#define REPO_H
-
-#include <sys/types.h>
-#include <sys/queue.h>
-
-
-#define CVS_MODULE_ISALIAS 0x01
-
-typedef struct cvs_module {
- char *cm_name;
- int cm_flags;
- char *cm_path; /* subpath for aliases, NULL otherwise */
-
- TAILQ_ENTRY(cvs_module) cm_link;
-} CVSMODULE;
-
-
-
-#define CVS_RPENT_UNKNOWN 0
-#define CVS_RPENT_DIR 1
-#define CVS_RPENT_RCSFILE 2
-
-typedef struct cvs_repoent CVSRPENT;
-
-/*
- * Repository locks
- * ================
- *
- * OpenCVS derives from the standard CVS mechanism in the way it manages locks
- * on the repository. GNU CVS uses files with 'rfl' and 'wfl' extensions for
- * read and write locks on particular directories.
- * Using the filesystem for locking semantics has one major drawback: a lock
- * can stay even after the process that created it is gone, if it didn't
- * perform the appropriate cleanup. This stale lock problem has been known
- * to happen with GNU CVS and an intervention from one of the repository
- * administrators is required before anyone else can access parts of the
- * repository.
- * In OpenCVS, a child cvsd needing to access a particular part of the tree
- * must first request a lock on that part of the tree by issuing a
- * CVS_MSG_LOCK message with the appropriate path. Although the code
- * supports locking at the file level, it should only be applied to the
- * directory level to avoid extra overhead. Both read and write locks can be
- * obtained, though with different behaviour. Multiple simultaneous read locks
- * can be obtained on the same entry, but there can only be one active write
- * lock. In the case where the directory
- * is already locked by another child, a lock wait is added to that entry
- * and the child requesting the lock will get a CVSD_MSG_LOCKPEND reply,
- * meaning that the lock has not been obtained but the child should block
- * until it receives a CVSD_MSG_OK or CVSD_MSG_ERR telling it whether it
- * obtained the lock or not. When a child is done modifying the locked portion
- * it should release its lock using the CVSD_MSG_UNLOCK request with the path.
- *
- * NOTES:
- * * The current locking mechanism allows a lock to be obtained on a
- * subportion of a part that has already been locked by another process.
- * * A lock on a directory only allows the owner to modify RCS files found
- * within that directory. Any modifications on subdirectories require the
- * process to lock those subdirectories as well.
- */
-
-#define CVS_LOCK_READ 1
-#define CVS_LOCK_WRITE 2
-
-
-struct cvs_lock {
- pid_t lk_owner;
- int lk_type;
- CVSRPENT *lk_ent; /* backpointer to the entry */
-
- TAILQ_ENTRY(cvs_lock) lk_link;
- TAILQ_ENTRY(cvs_lock) lk_chlink;
-};
-
-TAILQ_HEAD(cvs_lklist, cvs_lock);
-
-struct cvs_repoent {
- char *cr_name;
- int cr_type;
- CVSRPENT *cr_parent;
-
- union {
- TAILQ_HEAD(, cvs_repoent) files;
- } cr_data;
-
- struct cvs_lock *cr_wlock; /* write lock, NULL if none */
- struct cvs_lklist cr_rlocks; /* read locks */
- struct cvs_lklist cr_lkreq; /* pending lock requests */
-
- TAILQ_ENTRY(cvs_repoent) cr_link;
-};
-
-#define cr_files cr_data.files
-
-
-
-#define CVS_REPO_LOCKED 0x01
-#define CVS_REPO_READONLY 0x02
-#define CVS_REPO_CHKPERM 0x04
-
-TAILQ_HEAD(cvs_modlist, cvs_module);
-
-typedef struct cvs_repo {
- char *cr_path;
- int cr_flags;
- CVSRPENT *cr_tree;
-
- struct cvs_modlist cr_modules;
- TAILQ_ENTRY(cvs_repo) cr_link;
-} CVSREPO;
-
-
-
-
-CVSREPO *cvs_repo_load(const char *, int);
-void cvs_repo_free(CVSREPO *);
-int cvs_repo_alias(CVSREPO *, const char *, const char *);
-int cvs_repo_unalias(CVSREPO *, const char *);
-int cvs_repo_lockdir(CVSREPO *, const char *, int, pid_t);
-int cvs_repo_unlockdir(CVSREPO *, const char *, pid_t);
-int cvs_repo_lockent(CVSRPENT *, int, pid_t);
-int cvs_repo_unlockent(CVSRPENT *, pid_t);
-void cvs_repo_entfree(CVSRPENT *);
-void cvs_repo_modfree(CVSMODULE *);
-
-CVSRPENT *cvs_repo_find(CVSREPO *, const char *);
-
-
-#endif /* REPO_H */