Annotation of src/usr.bin/cvs/repo.h, Revision 1.1
1.1 ! jfb 1: /* $OpenBSD$ */
! 2: /*
! 3: * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
! 4: * All rights reserved.
! 5: *
! 6: * Redistribution and use in source and binary forms, with or without
! 7: * modification, are permitted provided that the following conditions
! 8: * are met:
! 9: *
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. The name of the author may not be used to endorse or promote products
! 13: * derived from this software without specific prior written permission.
! 14: *
! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 25: */
! 26:
! 27: #ifndef REPO_H
! 28: #define REPO_H
! 29:
! 30: #include <sys/types.h>
! 31: #include <sys/queue.h>
! 32:
! 33:
! 34: #define CVS_MODULE_ISALIAS 0x01
! 35:
! 36: typedef struct cvs_module {
! 37: char *cm_name;
! 38: int cm_flags;
! 39: char *cm_path; /* subpath for aliases, NULL otherwise */
! 40:
! 41: TAILQ_ENTRY(cvs_module) cm_link;
! 42: } CVSMODULE;
! 43:
! 44:
! 45:
! 46: #define CVS_RPENT_UNKNOWN 0
! 47: #define CVS_RPENT_DIR 1
! 48: #define CVS_RPENT_RCSFILE 2
! 49:
! 50: typedef struct cvs_repoent CVSRPENT;
! 51:
! 52: /*
! 53: * Repository locks
! 54: * ================
! 55: *
! 56: * OpenCVS derives from the standard CVS mechanism in the way it manages locks
! 57: * on the repository. GNU CVS uses files with 'rfl' and 'wfl' extensions for
! 58: * read and write locks on particular directories.
! 59: * Using the filesystem for locking semantics has one major drawback: a lock
! 60: * can stay even after the process that created it is gone, if it didn't
! 61: * perform the appropriate cleanup. This stale lock problem has been known
! 62: * to happen with GNU CVS and an intervention from one of the repository
! 63: * administrators is required before anyone else can access parts of the
! 64: * repository.
! 65: * In OpenCVS, a child cvsd needing to access a particular part of the tree
! 66: * must first request a lock on that part of the tree by issuing a
! 67: * CVS_MSG_LOCK message with the appropriate path. Although the code
! 68: * supports locking at the file level, it should only be applied to the
! 69: * directory level to avoid extra overhead. Both read and write locks can be
! 70: * obtained, though with different behaviour. Multiple simultaneous read locks
! 71: * can be obtained on the same entry, but there can only be one active write
! 72: * lock. In the case where the directory
! 73: * is already locked by another child, a lock wait is added to that entry
! 74: * and the child requesting the lock will get a CVSD_MSG_LOCKPEND reply,
! 75: * meaning that the lock has not been obtained but the child should block
! 76: * until it receives a CVSD_MSG_OK or CVSD_MSG_ERR telling it whether it
! 77: * obtained the lock or not. When a child is done modifying the locked portion
! 78: * it should release its lock using the CVSD_MSG_UNLOCK request with the path.
! 79: *
! 80: * NOTES:
! 81: * * The current locking mechanism allows a lock to be obtained on a
! 82: * subportion of a part that has already been locked by another process.
! 83: * * A lock on a directory only allows the owner to modify RCS files found
! 84: * within that directory. Any modifications on subdirectories require the
! 85: * process to lock those subdirectories as well.
! 86: */
! 87:
! 88: #define CVS_LOCK_READ 1
! 89: #define CVS_LOCK_WRITE 2
! 90:
! 91:
! 92: struct cvs_lock {
! 93: pid_t lk_owner;
! 94: int lk_type;
! 95: CVSRPENT *lk_ent; /* backpointer to the entry */
! 96:
! 97: TAILQ_ENTRY(cvs_lock) lk_link;
! 98: TAILQ_ENTRY(cvs_lock) lk_chlink;
! 99: };
! 100:
! 101: TAILQ_HEAD(cvs_lklist, cvs_lock);
! 102:
! 103: struct cvs_repoent {
! 104: char *cr_name;
! 105: int cr_type;
! 106: CVSRPENT *cr_parent;
! 107:
! 108: union {
! 109: TAILQ_HEAD(, cvs_repoent) files;
! 110: } cr_data;
! 111:
! 112: struct cvs_lock *cr_wlock; /* write lock, NULL if none */
! 113: struct cvs_lklist cr_rlocks; /* read locks */
! 114: struct cvs_lklist cr_lkreq; /* pending lock requests */
! 115:
! 116: TAILQ_ENTRY(cvs_repoent) cr_link;
! 117: };
! 118:
! 119: #define cr_files cr_data.files
! 120:
! 121:
! 122:
! 123: #define CVS_REPO_LOCKED 0x01
! 124: #define CVS_REPO_READONLY 0x02
! 125: #define CVS_REPO_CHKPERM 0x04
! 126:
! 127: TAILQ_HEAD(cvs_modlist, cvs_module);
! 128:
! 129: typedef struct cvs_repo {
! 130: char *cr_path;
! 131: int cr_flags;
! 132: CVSRPENT *cr_tree;
! 133:
! 134: struct cvs_modlist cr_modules;
! 135: TAILQ_ENTRY(cvs_repo) cr_link;
! 136: } CVSREPO;
! 137:
! 138:
! 139:
! 140:
! 141: CVSREPO* cvs_repo_load (const char *, int);
! 142: void cvs_repo_free (CVSREPO *);
! 143: int cvs_repo_alias (CVSREPO *, const char *, const char *);
! 144: int cvs_repo_unalias (CVSREPO *, const char *);
! 145: int cvs_repo_lockdir (CVSREPO *, const char *, int, pid_t);
! 146: int cvs_repo_unlockdir (CVSREPO *, const char *, pid_t);
! 147: int cvs_repo_lockent (CVSRPENT *, int, pid_t);
! 148: int cvs_repo_unlockent (CVSRPENT *, pid_t);
! 149: void cvs_repo_entfree (CVSRPENT *);
! 150: void cvs_repo_modfree (CVSMODULE *);
! 151:
! 152: CVSRPENT* cvs_repo_find (CVSREPO *, const char *);
! 153:
! 154:
! 155:
! 156: #endif /* REPO_H */