diff options
author | Joris Vink <joris@cvs.openbsd.org> | 2005-12-04 17:32:45 +0000 |
---|---|---|
committer | Joris Vink <joris@cvs.openbsd.org> | 2005-12-04 17:32:45 +0000 |
commit | c2c15e14eafea2b809b1b86011124ce5969a5698 (patch) | |
tree | 200570a5ca76dc1279f6d6ea0c3627830af1ea01 | |
parent | 8725bd0621d927b5c94792b68fe2660400146d71 (diff) |
bye obsolete junk;
"go ahead" and "nuke them" niallo@, xsa@
-rw-r--r-- | usr.bin/cvs/repo.c | 648 | ||||
-rw-r--r-- | usr.bin/cvs/repo.h | 155 |
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 */ |