+++ /dev/null
-diff -urN cvs-1.11.19.orig/INSTALL.cvsacl cvs-1.11.19/INSTALL.cvsacl
---- cvs-1.11.19.orig/INSTALL.cvsacl 1970-01-01 01:00:00.000000000 +0100
-+++ cvs-1.11.19/INSTALL.cvsacl 2004-11-26 13:48:57.000000000 +0100
-@@ -0,0 +1,23 @@
-+
-+Installation
-+
-+- copy the file acl.c under src directory of CVS source distribution.
-+ "cp acl.c /path/to/cvs-1.11.18/src/"
-+- copy the patch file cvsacl-patch-1.2.2 under CVS source distribution
-+ directory.
-+ "cp cvsacl-patch-1.2.2 /path/to/cvs-1.11.18/"
-+- cd to CVS source directory.
-+ "cd /path/to/cvs-1.11.18/"
-+- apply the patch.
-+ "patch -p0 < cvsacl-patch-1.2.2"
-+- if you are initializing the repository after applying patch, related
-+ config files will be created with init command.
-+ "cvs -d /path/to/repository init"
-+- if you already have a repository, you have to add the aclconfig file
-+ to your $CVSROOT/CVSROOT/. aclconfig.default is the default configuration
-+ file, you can rename it to aclconfig, and use it .
-+- modify aclconfig file, if you need to change some options.
-+- as the last step, you have to define yourself as acl administrator.
-+ "cvs -d /path/to/repository racl yourname:p -r ALL -d ALL"
-+ this command gives p (acl admin) rights to user (yourname),
-+ on all repository and tags/branches.
-diff -urN cvs-1.11.19.orig/README.cvsacl cvs-1.11.19/README.cvsacl
---- cvs-1.11.19.orig/README.cvsacl 1970-01-01 01:00:00.000000000 +0100
-+++ cvs-1.11.19/README.cvsacl 2004-11-26 13:47:23.000000000 +0100
-@@ -0,0 +1,282 @@
-+
-+CVS Access Control List Extension Patch
-+
-+http://cvsacl.sourceforge.net/
-+sbaris@users.sourceforge.net
-+
-+CVSACL is a patch for CVS. It adds two new subcommands
-+(acl & racl) to cvs for access control list management. It
-+provides advanced ACL definitions per modules, directories,
-+and files on branch/tag for remote cvs repository connections.
-+Execution of all CVS subcommands can be controlled with eight
-+different permissions.
-+ACL definitions works for only remote connections, local users
-+can access and modify repository, if unix file system permissions
-+allow. If you want all users to make remote connections to
-+repository, and not allow local users to access repository, you
-+have to set CVSServerRunAsUser keyword in aclconfig file
-+(explained below).
-+Still local users can use acl and racl subcommands to set
-+permissions on directories or files if they have acl admin rights (p)
-+on related directories or files.
-+So, in order to control all access to repository with this ACL
-+extension, you should use CVSServerRunAsUser keyword and force all
-+users to make remote connections. CVS repository administrator or
-+project managers have to use acl and racl subcommands to manage
-+permissions. But there is no gui client supporting these subcommands,
-+so you have to use cvs client itself either locally or remotely.
-+
-+
-+
-+
-+Permission Types
-+
-+- no access
-+ Command line character: n
-+ If a user given n permission, it is not allowed for any action on repository.
-+- read
-+ Command line character: r
-+ r permission gives only read access on repository.
-+ With r permission you are allowed to run cvs subcommands: annotate,
-+ checkout, diff, export, log, rannotate, rdiff, rlog, status.
-+- write
-+ Command line character: w
-+ w permission allows only cvs commit/checkin action.
-+ With w permission, you are not allowed to add/remove any file to/from
-+ repository, other permissions should be defines for that.
-+- tag
-+ Command line character: t
-+ t permission allows cvs tag and rtag subcommands to run, so you may
-+ control tagging and untagging operations. t permission includes r
-+ permission, since without reading you can not tag/untag a file.
-+ However t permission does not include write permission, you can not
-+ commit a file with only t permission.
-+- create
-+ Command line character: c
-+ c permission allows cvs add and import subcommands to run. To add or
-+ import a file/directory to repository, you have to given a c
-+ permission. Again, c permission does not include write permission,
-+ thus you may only add or import files, but you can not modify any
-+ existing file. After issuing add subcommand, you have to commit the file
-+ to complete adding. This commit subcommand is allowed because you are
-+ adding file and not modifying existing one.
-+- delete
-+ Command line character: d
-+ d permission allows cvs remove command to run. To remove a file/directory
-+ from repository, d permission have to set. It does not include write
-+ permission, so you can not modify contents of an existing file on repository.
-+- full access except admin rights
-+ Command line character: a
-+ a permission gives all access (above permissions) to repository, but it
-+ can not modify permissions. Only acl admins may modify the acl definitions.
-+- acl admin
-+ Command line character: p
-+ p permission means that user is an acl admin, so it is allowed to make anything on repository.
-+
-+
-+ACL Config Keywords
-+The administrative file aclconfig contains miscellaneous settings which
-+affect the behaviour of ACL extension. Currently defined keywords are:
-+
-+UseCVSACL=value
-+Use ACL definitions if set to yes. If you do not want to use ACLs for
-+some repositories in a patched CVS server, set this keyword to no. The default is no.
-+
-+UseCVSACLDefaultPermissions=value
-+Value can be any combination of valid permission types (w,r,t,c,d,t,a,p).
-+if there is no defined ACL and default permission in access file, or no
-+access file at all, this permissions are used. The default is p (admin rights),
-+if aclconfig file is created with cvs init.
-+
-+UseCVSGroups=value
-+CVS does not have a CVSROOT/passwd file. However it can be created manually
-+(format should be same as /etc/group). If value set to yes, CVS checks for
-+groups in file $CVSROOT/CVSROOT/group The default value is no.
-+
-+UseSystemGroups=value
-+Group memberships for users are checked in file /etc/group, if value is set
-+to yes. The default value is no.
-+
-+CVSACLFileLocation=value
-+Originally access file is put under CVSROOT/CVSROOT, if you want a different
-+location, set value to a valid path. The default value is $CVSROOT/CVSROOT/access.
-+
-+CVSGroupsFileLocation=value
-+IF UseCVSGroups is set to yes, CVS looks for a group file under $CVSROOT/CVSROOT.
-+To use a different location for group file set value to a valid path to group.
-+The default value is $CVSROOT/CVSROOT/group.
-+
-+UseSeparateACLFileForEachDir=value
-+If value is set to yes, a separate ACL file (access) is created for each
-+directory in repository. If you have a really big repository
-+(directories>10,000 and files>100,000), performance may drop due to a big
-+acl file, access. Setting the value to yes, may increase performance. Normally,
-+you will not need this. The default value is no.
-+
-+StopAtFirstPermissionDenied=value
-+If StopAtFirstPermissionDenied is set to yes
-+operation will stop at first permission denied message.
-+e.g. when you send commit command for a directory, if you dont
-+have write permission for just one file under the directory,
-+by default you will have a warning and commit will continue
-+on the other files. If you set this keyword to 'no', then
-+commit operation will be stopped when inaccassable file found.
-+Default is no.
-+
-+CVSServerRunAsUser=value
-+Set CVSServerRunAsUser keyword to a valid system user.
-+When a user make a remote connection to CVS, after successfull authentication
-+cvs process switch to run as that user, or defined system user in
-+$CVSROOT/CVSROOT/passwd. So, you also have to set unix file permissions accordingly.
-+A better solution:
-+Add a user and group such as both cvsadm.
-+Set CVSServerRunAsUser keyword to cvsadm.
-+Change unix file system permissions for your repository,
-+make cvsadm user and group owner, and read,write,execute permissions and setgid.
-+(chown cvsadm -R /path/to/your/repository)
-+(chgrp cvsadm -R /path/to/your/repository)
-+(chmod 2770 -R /path/to/your/repository)
-+Add yourself to cvsadm group (since you are ACL administrator).
-+Therefore, only users making remote connections will have access to repository
-+if you give rights. Local users can not access to repository via a cvs client or directly.
-+
-+
-+Command Line Usage Information
-+acl command is used on checked out files or directories. racl command is
-+used on repository without a working copy. Usage information can be obtained
-+with standard cvs --help command.
-+Output of cvs --help acl and cvs --help racl:
-+
-+Usage: cvs racl [user||group:permissions] [-Rl] [-r tag]
-+ -d [directory] -f [file]
-+ -R Process directories recursively.
-+ -r rev Existing revision/tag.
-+ -l List defined ACLs.
-+ -d dir Process on given directory.
-+ -f file Process on given file.
-+
-+Usage: cvs acl [user||group:permissions] [-Rl] [-r tag]
-+ -d [directory] -f [file]
-+ -R Process directories recursively.
-+ -r rev Existing revision/tag.
-+ -l List defined ACLs.
-+ -d dir Process on given directory.
-+ -f file Process on given file.
-+
-+You may directly set permissions for a user or group or add/remove
-+permissions with + and - signs to/from existing permissions.
-+If you do not give the branch/tag information, default value of HEAD
-+(main branch) will be used. You have to give branch/tag name with -r option.
-+You may type ALL for branch/tag field.
-+
-+While checking for permissions, it goes thorough the list below. So the highest
-+significant permission is the first item in list.
-+
-+- permissions assigned to username for specific directory or file.
-+- permissions assigned to group name for specific directory or file.
-+- permissions as defaults for specific directory or file.
-+- permissions assigned to parent folders (inherits from the first parent
-+ which permissions are assigned).
-+- permissions as repository defaults.
-+- permissions in aclconfig file.
-+
-+
-+
-+
-+Examples
-+ /cvs/
-+ |
-+ |
-+ +--projectA/
-+ | |
-+ | +---CVSROOT/
-+ | |
-+ | +---lib/
-+ | | |
-+ | | +---gnulib/
-+ | | |
-+ | | +---zlib/
-+ | |
-+ | +---src/
-+ | | |
-+ | | +---main.c
-+ | | |
-+ | | +---server.c
-+ | | |
-+ | | +---client.c
-+ | |
-+ | +---gui/
-+ |
-+ +--projectB/
-+We have above directory structure for a cvs repository, and no defined permissions.
-+
-+Setting main default permissions:
-+
-+$ cvs -d /cvs/projectA racl cvsadmin:p -r ALL -d ALL
-+$ cvs -d /cvs/projectA racl ALL:r -r ALL -d ALL
-+User cvsadmin will be an acl admin, and all other users will have only read
-+rights on all branches/tags in projectA repository. This is the default acl
-+definition and it overwrites default permissions in $CVSROOT/CVSROOT/aclconfig file.
-+
-+$ cvs -d /cvs/projectA racl ALL:r -r ALL -d ALL
-+$ cvs -d /cvs/projectA racl ALL:n -r ALL -d gui
-+After executing these two commands, all users will have read access on all
-+directories and files except gui directory. Everyone will be denied to access to gui
-+directory becase no access, n, permissions is set.
-+
-+Setting permissions directly on a file or directory:
-+
-+$ cvs -d /cvs/projectA racl userX:wcd -d lib
-+$ cvs -d /cvs/projectA racl group1:w -d lib
-+First command will set write, create, and delete permissions for userX on directory
-+lib with branch HEAD (since no branch/tag information given, branch defaults to HEAD).
-+Second command will set only write permission for group1 on directory lib with branch HEAD.
-+Members of group1 will have only commit rights on lib directory, branch HEAD, they can
-+not add or remove any file, just modify existing files.
-+If userX is also a member of group1, userX will have write, create, and delete permissions
-+because it is specifically given these permissions.
-+
-+$ cvs -d /cvs/projectA racl userY:wcd -r develStream -d lib
-+$ cvs -d /cvs/projectA racl userY:r -r integStream -d lib
-+These commands will give wcd permissions to userY on lib directory with tag develstream,
-+and r permissions on lib directory with tag integStream.
-+
-+$ cvs -d /cvs/projectA racl userZ:wcd -d src
-+$ cvs -d /cvs/projectA racl userZ:r -f src/main.c
-+First command will give wcd permissions to userZ on src directory, but only read
-+permission on file main.c in src directory.
-+
-+Using + and - signs to set permissions on a file or directory:
-+
-+$ cvs -d /cvs/projectA racl userZ:+t -d src
-+$ cvs -d /cvs/projectA racl userZ:-cd -d src
-+$ cvs -d /cvs/projectA racl userZ:-wt -d src
-+Before the first command, userZ has wcd permissions on src directory, after issuing
-+command it will have wcdt permissions. Tag permission will be added. UserZ has wcdt
-+permissions, and we execute the second command to remove create and delete permissions.
-+So userZ has wt permissions. In the last command we also remove wt permissions, finally
-+userZ has no defined permissions left, and it will use the default permissions if set.
-+
-+Listing permissions on a file or directory:
-+
-+$ cvs -d /cvs/projectA racl -l -d src
-+$ cvs -d /cvs/projectA racl -l -f src
-+$ cvs -d /cvs/projectA racl -l -f src/main.c
-+
-+First command will list the permissions for src directory.
-+Example output:
-+d src HEAD | userX:wcd group1:r | defaults:r
-+userX and group1 has assigned permissions, all other users will have default
-+permissions, which is only read.
-+
-+Second command will list the permissions for files in src directory.
-+Example output:
-+f src/main.c HEAD | userX:wcd group1:r | defaults:r
-+f src/server.c HEAD | userX:wcd group1:r | defaults:r
-+f src/client.c HEAD | userX:wcd group1:r | defaults:r
-+
-+Third command will list the permissions for main.c file in src directory.
-+Example output:
-+f src/main.c HEAD | userX:wcd group1:r | defaults:r
-+
-+
-diff -urN cvs-1.11.19.orig/aclconfig.default cvs-1.11.19/aclconfig.default
---- cvs-1.11.19.orig/aclconfig.default 1970-01-01 01:00:00.000000000 +0100
-+++ cvs-1.11.19/aclconfig.default 2004-11-26 13:47:34.000000000 +0100
-@@ -0,0 +1,33 @@
-+# Set `UseCVSACL' to yes to use CVS ACL feature.
-+UseCVSACL=yes
-+
-+# Default CVS ACL Permission are to use.
-+#CVSACLDefaultPermissions=a
-+
-+# Default file location for CVS ACL file (access) is CVSROOT/access.
-+# If you want to use a different location, define it below.
-+#CVSACLFileLocation=/path/to/cvs/access
-+
-+# Set `UseSystemGroups' to yes to use system group definitions (/etc/group).
-+UseSystemGroups=yes
-+
-+# Set `UseCVSGroups' to yes to use another group file.
-+#UseCVSGroups=yes
-+
-+# Default file location for CVS groups file is CVSROOT/group.
-+# If you want to use a different location, define it below.
-+#CVSGroupsFileLocation=/path/to/cvs/group
-+
-+# Set UseSeparateACLFileForEachDir to yes in order to use a
-+# separate 'access' file for each directory.
-+# This increased the performance if you have really big repository.
-+#UseSeparateACLFileForEachDir=no
-+
-+# If StopAtFirstPermissionDenied is set to yes
-+# operation will stop at first permission denied message.
-+# Default is no.
-+#StopAtFirstPermissionDenied=no
-+
-+# Set CVSServerRunAsUser to a system user, in order CVS server
-+# to run as.
-+#CVSServerRunAsUser=runascvsuser
-diff -urN cvs-1.11.19.orig/src/Makefile.am cvs-1.11.19/src/Makefile.am
---- cvs-1.11.19.orig/src/Makefile.am 2005-03-14 19:49:29.000000000 +0100
-+++ cvs-1.11.19/src/Makefile.am 2005-03-14 19:55:09.000000000 +0100
-@@ -31,6 +31,7 @@
-
- # The cvs executable
- cvs_SOURCES = \
-+ acl.c \
- add.c \
- admin.c \
- annotate.c \
-diff -urN cvs-1.11.19.orig/src/Makefile.in cvs-1.11.19/src/Makefile.in
---- cvs-1.11.19.orig/src/Makefile.in 2005-02-01 00:11:15.000000000 +0100
-+++ cvs-1.11.19/src/Makefile.in 2005-03-14 19:55:09.000000000 +0100
-@@ -69,20 +69,20 @@
- am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)"
- binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
- PROGRAMS = $(bin_PROGRAMS)
--am_cvs_OBJECTS = add.$(OBJEXT) admin.$(OBJEXT) annotate.$(OBJEXT) \
-- buffer.$(OBJEXT) checkin.$(OBJEXT) checkout.$(OBJEXT) \
-- classify.$(OBJEXT) client.$(OBJEXT) commit.$(OBJEXT) \
-- create_adm.$(OBJEXT) cvsrc.$(OBJEXT) diff.$(OBJEXT) \
-- edit.$(OBJEXT) entries.$(OBJEXT) error.$(OBJEXT) \
-- expand_path.$(OBJEXT) fileattr.$(OBJEXT) filesubr.$(OBJEXT) \
-- find_names.$(OBJEXT) hardlink.$(OBJEXT) hash.$(OBJEXT) \
-- history.$(OBJEXT) ignore.$(OBJEXT) import.$(OBJEXT) \
-- lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) logmsg.$(OBJEXT) \
-- main.$(OBJEXT) mkmodules.$(OBJEXT) modules.$(OBJEXT) \
-- myndbm.$(OBJEXT) no_diff.$(OBJEXT) parseinfo.$(OBJEXT) \
-- patch.$(OBJEXT) rcs.$(OBJEXT) rcscmds.$(OBJEXT) \
-- recurse.$(OBJEXT) release.$(OBJEXT) remove.$(OBJEXT) \
-- repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) \
-+am_cvs_OBJECTS = acl.$(OBJEXT) add.$(OBJEXT) admin.$(OBJEXT) \
-+ annotate.$(OBJEXT) buffer.$(OBJEXT) checkin.$(OBJEXT) \
-+ checkout.$(OBJEXT) classify.$(OBJEXT) client.$(OBJEXT) \
-+ commit.$(OBJEXT) create_adm.$(OBJEXT) cvsrc.$(OBJEXT) \
-+ diff.$(OBJEXT) edit.$(OBJEXT) entries.$(OBJEXT) \
-+ error.$(OBJEXT) expand_path.$(OBJEXT) fileattr.$(OBJEXT) \
-+ filesubr.$(OBJEXT) find_names.$(OBJEXT) hardlink.$(OBJEXT) \
-+ hash.$(OBJEXT) history.$(OBJEXT) ignore.$(OBJEXT) \
-+ import.$(OBJEXT) lock.$(OBJEXT) log.$(OBJEXT) login.$(OBJEXT) \
-+ logmsg.$(OBJEXT) main.$(OBJEXT) mkmodules.$(OBJEXT) \
-+ modules.$(OBJEXT) myndbm.$(OBJEXT) no_diff.$(OBJEXT) \
-+ parseinfo.$(OBJEXT) patch.$(OBJEXT) rcs.$(OBJEXT) \
-+ rcscmds.$(OBJEXT) recurse.$(OBJEXT) release.$(OBJEXT) \
-+ remove.$(OBJEXT) repos.$(OBJEXT) root.$(OBJEXT) run.$(OBJEXT) \
- scramble.$(OBJEXT) server.$(OBJEXT) stack.$(OBJEXT) \
- status.$(OBJEXT) subr.$(OBJEXT) tag.$(OBJEXT) update.$(OBJEXT) \
- version.$(OBJEXT) vers_ts.$(OBJEXT) watch.$(OBJEXT) \
-@@ -206,6 +206,7 @@
-
- # The cvs executable
- cvs_SOURCES = \
-+ acl.c \
- add.c \
- admin.c \
- annotate.c \
-@@ -384,6 +385,7 @@
- distclean-compile:
- -rm -f *.tab.c
-
-+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acl.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/add.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/admin.Po@am__quote@
- @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/annotate.Po@am__quote@
-diff -urN cvs-1.11.19.orig/src/acl.c cvs-1.11.19/src/acl.c
---- cvs-1.11.19.orig/src/acl.c 1970-01-01 01:00:00.000000000 +0100
-+++ cvs-1.11.19/src/acl.c 2004-11-26 13:50:48.000000000 +0100
-@@ -0,0 +1,2032 @@
-+/*
-+ *
-+ * CVS ACCESS CONTROL LIST EXTENSION
-+ *
-+ * sbaris@users.sourceforge.net
-+ *
-+ * http://cvsacl.sourceforge.net/
-+ *
-+ * CVSACL is a patch for CVS versions
-+ * - cvs-1.11.18
-+ *
-+ * It adds two new subcommands (acl & racl) to cvs for access control
-+ * list management.
-+ * It provides advanced ACL definitions per modules, directories,
-+ * and files on branch/tag for remote cvs repository connections.
-+ * Execution of all CVS subcommands can be controlled with eight
-+ * different permissions.
-+ * ACL definitions works for only remote connections, local users can
-+ * access and modify repository, if unix file system permissions allow.
-+ * If you want all users to make remote connections to repository,
-+ * and not allow local users to access repository, you have to set
-+ * CVSServerRunAsUser keyword in aclconfig file (explained below).
-+ * Still local users can use acl and racl subcommands to set permissions
-+ * on directories or files if they have acl admin rights (p) on related
-+ * directories or files.
-+ * So, in order to control all access to repository with this ACL extension,
-+ * you should use CVSServerRunAsUser keyword and force all users to make
-+ * remote connections.
-+ * CVS repository administrator or project managers have to use acl and racl
-+ * subcommands to manage permissions. But there is no gui client supporting
-+ * these subcommands, so you have to use cvs client itself either
-+ * locally or remotely.
-+ *
-+ *
-+ * Permission Types:
-+ * - no permission (n) (1)
-+ * - all permissions (a) (2)
-+ * - write permission (w) (3)
-+ * - tag permission (t) (4)
-+ * - read permission (r) (5)
-+ * - add permission (c) (6)
-+ * - remove permission (d) (7)
-+ * - permission change (p) (8)
-+ *
-+ *
-+ *
-+ *
-+ * ********************************************************************
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 1, or (at your option)
-+ * any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ * *******************************************************************
-+ *
-+ */
-+
-+#include "cvs.h"
-+#include "getline.h"
-+#include <grp.h>
-+
-+static int acl_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-+static Dtype acl_dirproc PROTO ((void *callerdat, const char *dir, const char *repos,
-+ const char *update_dir, List *entries));
-+
-+static int acllist_fileproc PROTO ((void *callerdat, struct file_info *finfo));
-+static Dtype acllist_dirproc PROTO ((void *callerdat, const char *dir, const char *repos,
-+ const char *update_dir, List *entries));
-+
-+static void acllist_print PROTO ((char *line, const char *obj));
-+
-+static int racl_proc PROTO((int argc, char **argv, char *xwhere,
-+ char *mwhere, char *mfile, int shorten,
-+ int local_specified, char *mname, char *msg));
-+
-+FILE *open_accessfile (char *xmode, const char *repos, char **fname);
-+FILE *open_groupfile (char *xmode);
-+
-+char *get_perms (char *xperms);
-+char *make_perms (char *xperms, char *xfounduserpart, char **xerrmsg);
-+
-+static char *cache_repository;
-+static int cache_retval;
-+static int founddeniedfile;
-+static int cache_perm;
-+
-+static int is_racl;
-+
-+int use_cvs_acl = 0;
-+char *cvs_acl_default_permissions;
-+int use_cvs_groups = 0;
-+int use_system_groups = 0;
-+int use_separate_acl_file_for_each_dir = 0;
-+char *cvs_acl_file_location = NULL;
-+char *cvs_groups_file_location = NULL;
-+char *cvs_server_run_as = NULL;
-+int stop_at_first_permission_denied = 0;
-+
-+char *tag = NULL;
-+
-+char *muser;
-+char *mperms;
-+static int defaultperms;
-+
-+static char *default_perms_object;
-+char *default_part_perms_accessfile;
-+
-+int acldir = 0;
-+int aclfile = 0;
-+int listacl = 0;
-+
-+int userfound;
-+int groupfound;
-+
-+char *dirs[25];
-+
-+int aclconfig_default_used;
-+
-+static const char *const acl_usage[] =
-+ {
-+ "Usage: %s %s [user||group:permissions] [-Rl] [-r tag]\n -d [directory] -f [file]\n",
-+ "\t-R\tProcess directories recursively.\n",
-+ "\t-r rev\tExisting revision/tag.\n",
-+ "\t-l\tList defined ACLs.\n",
-+ "\t-d dir\tProcess on given directory.\n",
-+ "\t-f file\tProcess on given file.\n",
-+ "(Specify the --help global option for a list of other help options)\n",
-+ NULL
-+ };
-+
-+static const char *const racl_usage[] =
-+ {
-+ "Usage: %s %s [user||group:permissions] [-Rl] [-r tag]\n -d [directory] -f [file]\n",
-+ "\t-R\tProcess directories recursively.\n",
-+ "\t-r rev\tExisting revision/tag.\n",
-+ "\t-l\tList defined ACLs.\n",
-+ "\t-d dir\tProcess on given directory.\n",
-+ "\t-f file\tProcess on given file.\n",
-+ "(Specify the --help global option for a list of other help options)\n",
-+ NULL
-+ };
-+
-+
-+int
-+access_allowed (file, repos, tag, perm, mline, mpos, usecache)
-+char *file;
-+char *repos;
-+char *tag;
-+int perm;
-+char **mline;
-+int *mpos;
-+int usecache;
-+{
-+ int retval = 0;
-+ int foundline = 0;
-+ FILE *accessfp;
-+
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+
-+ char *part_type = NULL;
-+ char *part_object = NULL;
-+ char *part_tag = NULL;
-+ char *part_perms = NULL;
-+ char *xline;
-+ int x;
-+
-+ char *iline;
-+
-+ char *tempv;
-+ char *tempc;
-+ size_t tempsize;
-+ int intcount;
-+
-+ int oneaccessfile = 0;
-+ int accessfilecount;
-+
-+ int signlevel = -1;
-+
-+ int dadmin = 0;
-+
-+ const char *repository;
-+ char *filefullname = NULL;
-+
-+
-+ userfound = 0;
-+ groupfound = 0;
-+
-+
-+ if (defaultperms)
-+ {
-+ repository = xstrdup ("ALL");
-+ }
-+ else
-+ repository = Short_Repository (repos);
-+
-+ /* cache */
-+ if (usecache
-+ && cache_repository != NULL
-+ && strcmp (cache_repository, repository) == 0
-+ && !founddeniedfile
-+ && perm == cache_perm)
-+ return (cache_retval);
-+ else
-+ {
-+ free(cache_repository);
-+ cache_repository = xstrdup(repository);
-+ cache_perm = perm;
-+ }
-+
-+ if (file != NULL)
-+ {
-+ filefullname = xmalloc (strlen (repository)
-+ + strlen (file)
-+ + 2);
-+
-+ strcpy (filefullname, repository);
-+ strcat (filefullname, "/");
-+ strcat (filefullname, file);
-+ }
-+
-+
-+ iline = xstrdup(repository);
-+
-+ tempv = strtok(iline, "/\t");
-+ tempc = xstrdup(tempv);
-+ tempsize = strlen(tempc);
-+
-+ intcount = 0;
-+
-+ dirs[intcount] = xstrdup(tempc);
-+
-+ while ((tempv = strtok(NULL, "/\t")) != NULL)
-+ {
-+ intcount++;
-+
-+ xrealloc_and_strcat(&tempc, &tempsize, "/");
-+ xrealloc_and_strcat(&tempc, &tempsize, tempv);
-+
-+ dirs[intcount] = xstrdup(tempc);
-+ }
-+
-+ accessfilecount = intcount;
-+
-+ if (file != NULL)
-+ {
-+ intcount++;
-+ dirs[intcount] = xstrdup(filefullname);
-+ }
-+
-+ for (accessfilecount; accessfilecount >= 0 && !oneaccessfile; accessfilecount--)
-+ {
-+ if (!use_separate_acl_file_for_each_dir)
-+ oneaccessfile = 1;
-+ else if (use_separate_acl_file_for_each_dir)
-+ oneaccessfile = 0;
-+
-+ if (acldir || aclfile)
-+ oneaccessfile = 1;
-+
-+ if (oneaccessfile)
-+ accessfp = open_accessfile ("r", repository, NULL);
-+ else
-+ accessfp = open_accessfile ("r", dirs[accessfilecount], NULL);
-+
-+ if (accessfp != NULL)
-+ {
-+ while (getline (&line, &line_allocated, accessfp) >= 0)
-+ {
-+
-+ if (line[0] == '#' || line[0] == '\0' || line[0] == '\n')
-+ continue;
-+
-+ xline = xstrdup (line);
-+ part_type = strtok (line, ":\t");
-+ part_object = strtok (NULL, ":\t");
-+ part_tag = strtok (NULL, ":\t");
-+ part_perms = strtok (NULL, ":\t");
-+
-+ for (x = intcount; x >= signlevel && x != -1; x--)
-+ {
-+ if (strcmp (dirs[x], part_object) == 0)
-+ {
-+ if (valid_tag (part_tag, tag))
-+ {
-+ foundline = 1;
-+
-+ if (listacl || acldir || aclfile)
-+ {
-+ *mline = xstrdup (xline);
-+ *mpos = ftell (accessfp);
-+ }
-+
-+ if (valid_perm (part_perms, perm))
-+ {
-+ if (signlevel == x)
-+ {
-+ if (strncmp(part_tag, "ALL", 3) != 0 && !aclconfig_default_used)
-+ retval = 1;
-+ }
-+ else if (!aclconfig_default_used)
-+ {
-+ signlevel = x;
-+ retval = 1;
-+ }
-+ else {
-+ }
-+ }
-+ else
-+ {
-+ if (signlevel == x)
-+ {
-+ if (strncmp(part_tag, "ALL", 3) != 0 && !aclconfig_default_used)
-+ retval = 0;
-+ }
-+ else if (!aclconfig_default_used)
-+ {
-+ signlevel = x;
-+ retval = 0;
-+
-+ if (strncmp (part_type, "f", 1) == 0)
-+ founddeniedfile = 1;
-+ }
-+ else {
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (strncmp (xline, "d:ALL", 5) == 0 && (!groupfound && !userfound || listacl))
-+ {
-+ /* a default found */
-+ if (valid_tag (part_tag, tag))
-+ {
-+ foundline = 1;
-+
-+ default_part_perms_accessfile = xstrdup (part_perms);
-+
-+ if (valid_perm (part_perms, perm))
-+ {
-+ retval = 1;
-+
-+ if (perm == 8)
-+ dadmin = 1;
-+ }
-+ else
-+ retval = 0;
-+ }
-+ }
-+
-+ }
-+ if (fclose (accessfp) == EOF)
-+ error (1, errno, "cannot close 'access' file");
-+
-+ }
-+ }
-+
-+ if (!foundline)
-+ {
-+ /* DEFAULT */
-+ if (valid_perm (NULL, perm))
-+ retval = 1;
-+ else
-+ retval = 0;
-+ }
-+
-+ if (dadmin)
-+ {
-+ retval = dadmin;
-+ }
-+
-+ cache_retval = retval;
-+
-+ free (filefullname);
-+
-+ return (retval);
-+}
-+
-+/* Returns 1 if successful, 0 if not. */
-+int
-+valid_tag (part_tag, tag)
-+char *part_tag;
-+char *tag;
-+{
-+ if (acldir || aclfile)
-+ return (0);
-+
-+ if (tag == NULL)
-+ tag = xstrdup ("HEAD");
-+
-+ if (strcmp (part_tag, "ALL") == 0)
-+ return (1);
-+
-+ if (strcmp (tag, part_tag) == 0)
-+ return (1);
-+ else
-+ return (0);
-+}
-+
-+/* Returns 1 if successful, 0 if not. */
-+int
-+valid_perm (part_perms, perm)
-+char *part_perms;
-+int perm;
-+{
-+ char *perms;
-+ int retval = 0;
-+
-+ perms = get_perms (part_perms);
-+
-+ /* Allow, if nothing found. */
-+ if (perms[0] == '\0')
-+ return (1);
-+
-+
-+ if (strstr (perms, "n"))
-+ retval = 0; /* no access allowed, exit */
-+ if (strstr (perms, "p"))
-+ retval = 1; /* admin rights */
-+ else if (strstr (perms, "a") && perm != 8)
-+ retval = 1; /* all access allowed, exit */
-+ else
-+ switch (perm)
-+ {
-+ case 3: /* write permission */
-+ if (strstr (perms, "w"))
-+ retval = 1;
-+ break;
-+ case 4: /* tag permission */
-+ if (strstr (perms, "t"))
-+ retval = 1;
-+ break;
-+ case 5: /* read permission */
-+ if (strstr (perms, "w") || strstr (perms, "t") || strstr (perms, "c") ||
-+ strstr (perms, "d") || strstr (perms, "r"))
-+ retval = 1;
-+ break;
-+ case 6: /* create permission */
-+ if (strstr (perms, "c"))
-+ retval = 1;
-+ break;
-+ case 7: /* delete permission */
-+ if (strstr (perms, "d"))
-+ retval = 1;
-+ break;
-+ case 8: /* permission change */
-+ if (strstr (perms, "p"))
-+ retval = 1;
-+ break;
-+ default:
-+ retval = 0; /* never reached */
-+ break;
-+ }
-+
-+ return (retval);
-+}
-+
-+char *
-+get_perms (part_perms)
-+char *part_perms;
-+
-+{
-+ char *username;
-+ char *xperms;
-+ size_t xperms_len = 1;
-+
-+ FILE *groupfp;
-+
-+ char *usr;
-+ char *per;
-+ char *founduser = NULL;
-+ char *foundall = NULL;
-+ int default_checked = 0;
-+
-+ aclconfig_default_used = 0;
-+
-+ xperms = xmalloc (xperms_len);
-+ xperms[0] = '\0';
-+
-+ username = getcaller ();
-+
-+ /* no defined acl, no default acl in access file,
-+ or no access file at all */
-+ if (part_perms == NULL)
-+ if (cvs_acl_default_permissions)
-+ {
-+ aclconfig_default_used = 1;
-+ return (cvs_acl_default_permissions);
-+ }
-+ else
-+ return (xperms);
-+
-+check_default:
-+ founduser = strstr (part_perms, username);
-+ foundall = strstr (part_perms, "ALL!");
-+
-+ if (founduser)
-+ {
-+ usr = strtok (founduser, "!\t");
-+ per = strtok (NULL, ",\t");
-+
-+ if (strcmp (usr, username) == 0)
-+ {
-+ xperms = xstrdup (per);
-+ xperms_len = strlen (xperms);
-+
-+ userfound = 1;
-+ }
-+ }
-+ else
-+ {
-+ if (use_system_groups) {
-+ struct group *griter;
-+ setgrent ();
-+ while (griter = getgrent ()) {
-+ char **users=griter->gr_mem;
-+ int index = 0;
-+ char *userchk = users [index++];
-+ while(userchk != NULL) {
-+ if(strcmp (userchk, username) == 0)
-+ break;
-+ userchk = users[index++];
-+ }
-+ if (userchk != NULL) {
-+ char *grp;
-+ if ((grp = strstr (part_perms, griter->gr_name)) && grp[strlen (griter->gr_name)] == '!') {
-+ char *gperm = strtok (grp, "!\t");
-+ gperm = strtok (NULL, ",\t");
-+ xrealloc_and_strcat (&xperms, &xperms_len, gperm);
-+
-+ groupfound = 1;
-+ }
-+ }
-+ }
-+ endgrent ();
-+ }
-+ else if (use_cvs_groups) {
-+ groupfp = open_groupfile ("r");
-+ if (groupfp != NULL)
-+ {
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+
-+ while (getline (&line, &line_allocated, groupfp) >= 0)
-+ {
-+ if (strstr (line, username))
-+ {
-+ char *temp;
-+ temp = strstr (line, username);
-+
-+ if (temp[strlen (username)] == ','
-+ || temp[strlen (username)] == ' '
-+ || temp[strlen (username)] == '\n')
-+ {
-+ char *tmp;
-+ tmp = strtok (line, ":\t");
-+ if (strcmp (tmp, username) != 0)
-+ {
-+ char *grp;
-+ if ((grp = strstr (part_perms, tmp)))
-+ if (grp[strlen (tmp)] == '!')
-+ {
-+ char *gperm;
-+ gperm = strtok (grp, "!\t");
-+ gperm = strtok (NULL, ",\t");
-+
-+ xrealloc_and_strcat (&xperms, &xperms_len, gperm);
-+
-+ groupfound = 1;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ if (fclose (groupfp) == EOF)
-+ error (1, errno, "cannot close 'group' file");
-+ }
-+ }
-+ }
-+
-+ if (foundall && (!groupfound && !userfound))
-+ {
-+ usr = strtok (strstr (part_perms, "ALL!"), "!\t");
-+ per = strtok (NULL, ",\t");
-+
-+ if (!default_checked)
-+ default_perms_object = xstrdup (per);
-+
-+ if (xperms[0] == '\0')
-+ {
-+ xperms = xstrdup (per);
-+ xperms_len = strlen (xperms);
-+ }
-+ }
-+ else if (xperms[0] == '\0' && !default_checked && default_part_perms_accessfile)
-+ {
-+ part_perms = xstrdup (default_part_perms_accessfile);
-+ default_checked = 1;
-+
-+ goto check_default;
-+ }
-+
-+ if (xperms[0] != '\0' && strcmp (xperms, "x") == 0)
-+ {
-+ if (default_perms_object)
-+ xperms = xstrdup (default_perms_object);
-+ else if (default_part_perms_accessfile)
-+ {
-+ part_perms = default_part_perms_accessfile;
-+ default_checked = 1;
-+ goto check_default;
-+ }
-+ else if (cvs_acl_default_permissions)
-+ {
-+ aclconfig_default_used = 1;
-+ xperms = xstrdup (cvs_acl_default_permissions);
-+ }
-+ }
-+
-+ if (xperms[0] == '\0' && cvs_acl_default_permissions)
-+ {
-+ aclconfig_default_used = 1;
-+ xperms = xstrdup (cvs_acl_default_permissions);
-+ }
-+
-+ return (xperms);
-+}
-+
-+
-+int
-+cvsacl (argc, argv)
-+int argc;
-+char **argv;
-+{
-+ char *chdirrepository;
-+ int c;
-+ int err = 0;
-+ int usetag = 0;
-+ int recursive = 0;
-+
-+ int k;
-+
-+ int which;
-+ char *where;
-+
-+ is_racl = (strcmp (cvs_cmd_name, "racl") == 0);
-+
-+ if (argc == -1)
-+ usage (is_racl ? racl_usage : acl_usage);
-+
-+ /* parse the args */
-+ optind = 0;
-+
-+ while ((c = getopt (argc, argv, "Rr:dfl")) != -1)
-+ {
-+ switch (c)
-+ {
-+ case 'R':
-+ recursive = 1;
-+ break;
-+ case 'r':
-+ tag = xstrdup (optarg);
-+ break;
-+ case 'd':
-+ acldir = 1;
-+ break;
-+ case 'f':
-+ aclfile = 1;
-+ break;
-+ case 'l':
-+ listacl = 1;
-+ break;
-+ case '?':
-+ default:
-+ usage (is_racl ? racl_usage : acl_usage);
-+ break;
-+ }
-+ }
-+
-+ argc -= optind;
-+ argv += optind;
-+
-+ if (!acldir && !aclfile)
-+ usage (is_racl ? racl_usage : acl_usage);
-+ if (acldir && aclfile)
-+ usage (is_racl ? racl_usage : acl_usage);
-+
-+ if (listacl)
-+ if (strstr (argv[0], ":"))
-+ usage (is_racl ? racl_usage : acl_usage);
-+ if (!listacl)
-+ if (!strstr (argv[0], ":"))
-+ usage (is_racl ? racl_usage : acl_usage);
-+
-+ if (argc < (is_racl ? 1 : 1))
-+ usage (is_racl ? racl_usage : acl_usage);
-+
-+#ifdef CLIENT_SUPPORT
-+
-+ if (current_parsed_root->isremote)
-+ {
-+ start_server ();
-+ ign_setup ();
-+
-+ if(recursive)
-+ send_arg ("-R");
-+
-+ if (acldir)
-+ send_arg ("-d");
-+
-+ if (aclfile)
-+ send_arg ("-f");
-+
-+ if (listacl)
-+ send_arg ("-l");
-+
-+ if(tag)
-+ {
-+ send_arg ("-r");
-+ send_arg (tag);
-+ }
-+
-+ send_arg ("--");
-+
-+ if (!listacl)
-+ {
-+ send_arg (argv[0]);
-+
-+ argc--;
-+ argv++;
-+ }
-+
-+ if (is_racl)
-+ {
-+ int i;
-+ for (i = 0; i < argc; ++i)
-+ send_arg (argv[i]);
-+
-+ send_to_server ("racl\012",0);
-+ }
-+ else
-+ {
-+ send_files (argc, argv, recursive, 0, SEND_NO_CONTENTS);
-+ send_file_names (argc, argv, SEND_EXPAND_WILD);
-+ send_to_server ("acl\012", 0);
-+ }
-+
-+ return get_responses_and_close ();
-+ }
-+#endif
-+
-+#ifdef SERVER_SUPPORT
-+
-+ if (!listacl)
-+ {
-+ muser = strtok (argv[0], ":\t");
-+ mperms = strtok (NULL, ":\t");
-+
-+ /* if set to 'default' */
-+ if ((strlen (mperms) == 7) && (strncmp (mperms, "default", 7) == 0))
-+ mperms = xstrdup ("x");
-+
-+ /* Check that the given permissions are valid. */
-+ if (!given_perms_valid (mperms))
-+ error (1,0,"Invalid permissions: '%s'", mperms);
-+
-+ argc--;
-+ argv++;
-+ }
-+
-+
-+ if (!tag)
-+ tag = xstrdup ("HEAD");
-+
-+ if (!cvs_casecmp (argv[0], "ALL"))
-+ {
-+ argv[0] = xstrdup (".");
-+ defaultperms = 1;
-+ if (!use_separate_acl_file_for_each_dir)
-+ {
-+ recursive = 0;
-+ }
-+
-+ }
-+
-+ if (is_racl)
-+ {
-+ DBM *db;
-+ int i;
-+ db = open_module ();
-+ for (i = 0; i < argc; i++)
-+ {
-+ err += do_module (db, argv[i], MISC, "ACL ing: ",
-+ racl_proc, (char *) NULL, 0, !recursive, 0,
-+ 0, NULL);
-+ }
-+ close_module (db);
-+ }
-+ else
-+ {
-+ err = racl_proc (argc + 1, argv - 1, NULL, NULL, NULL, 0, !recursive, NULL,
-+ NULL);
-+ }
-+ if (err)
-+ error (1, 0, "an error accured");
-+
-+ return (err);
-+
-+#endif
-+}
-+
-+static int
-+racl_proc (argc, argv, xwhere, mwhere, mfile, shorten, local, mname, msg)
-+int argc;
-+char **argv;
-+char *xwhere;
-+char *mwhere;
-+char *mfile;
-+int shorten;
-+int local;
-+char *mname;
-+char *msg;
-+{
-+ char *myargv[2];
-+ int err = 0;
-+ int which;
-+ char *repository;
-+ char *where;
-+
-+ if (is_racl)
-+ {
-+ repository = xmalloc (strlen (current_parsed_root->directory) + strlen (argv[0])
-+ + (mfile == NULL ? 0 : strlen (mfile) + 1) + 2);
-+
-+ (void) sprintf (repository, "%s/%s", current_parsed_root->directory, argv[0]);
-+ where = xmalloc (strlen (argv[0]) + (mfile == NULL ? 0 : strlen (mfile) + 1)
-+ + 1);
-+ (void) strcpy (where, argv[0]);
-+
-+ /* if mfile isn't null, we need to set up to do only part of the module */
-+ if (mfile != NULL)
-+ {
-+ char *cp;
-+ char *path;
-+
-+ /* if the portion of the module is a path, put the dir part on repos */
-+ if ((cp = strrchr (mfile, '/')) != NULL)
-+ {
-+ *cp = '\0';
-+ (void) strcat (repository, "/");
-+ (void) strcat (repository, mfile);
-+ (void) strcat (where, "/");
-+ (void) strcat (where, mfile);
-+ mfile = cp + 1;
-+ }
-+
-+ /* take care of the rest */
-+ path = xmalloc (strlen (repository) + strlen (mfile) + 5);
-+ (void) sprintf (path, "%s/%s", repository, mfile);
-+ if (isdir (path))
-+ {
-+ /* directory means repository gets the dir tacked on */
-+ (void) strcpy (repository, path);
-+ (void) strcat (where, "/");
-+ (void) strcat (where, mfile);
-+ }
-+ else
-+ {
-+ myargv[0] = argv[0];
-+ myargv[1] = mfile;
-+ argc = 2;
-+ argv = myargv;
-+ }
-+ free (path);
-+ }
-+
-+ /* cd to the starting repository */
-+ if ( CVS_CHDIR (repository) < 0)
-+ {
-+ error (0, errno, "cannot chdir to %s", repository);
-+ free (repository);
-+ return (1);
-+ }
-+
-+ /* End section which is identical to patch_proc. */
-+
-+ which = W_REPOS | W_ATTIC;
-+ }
-+ else
-+ {
-+ where = NULL;
-+ which = W_LOCAL | W_REPOS | W_ATTIC;
-+ }
-+ if (listacl)
-+ err = start_recursion (acllist_fileproc, NULL, acllist_dirproc, NULL, NULL,
-+ argc - 1, argv + 1, local, which, 0, 0, (char *) where, 1,
-+ repository);
-+ else
-+ err = start_recursion (acl_fileproc, NULL, acl_dirproc, NULL, NULL,
-+ argc - 1, argv + 1, local, which, 0, 0, (char *) where, 1,
-+ repository);
-+
-+ return (err);
-+}
-+
-+
-+static int
-+acl_fileproc (callerdat, finfo)
-+void *callerdat;
-+struct file_info *finfo;
-+{
-+ Vers_TS *vers;
-+
-+ FILE *accessfp;
-+
-+ char *filefullname;
-+
-+ char *founduserpart = NULL;
-+ char *newuserpart = NULL;
-+ char *otheruserparts = NULL;
-+ size_t otherslen = 0;
-+
-+ const char *frepository;
-+ int foundline = 0;
-+
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+ int linelen;
-+
-+ char *part_type = NULL;
-+ char *part_object = NULL;
-+ char *part_tag = NULL;
-+ char *part_perms = NULL;
-+ char *wperms;
-+ char *userpart;
-+
-+ char *errmsg;
-+
-+ int pos;
-+
-+ if (!aclfile)
-+ return (0);
-+
-+ frepository = Short_Repository (finfo->repository);
-+
-+ filefullname = xmalloc (strlen (frepository)
-+ + strlen (finfo->file)
-+ + 2);
-+ strcpy (filefullname, frepository);
-+ strcat (filefullname, "/");
-+ strcat (filefullname, finfo->file);
-+
-+ if (!access_allowed (finfo->file, finfo->repository, tag, 8, &line, &pos, 0))
-+ error (1,0,"You do not have acl admin rights on '%s'", frepository);
-+
-+ if (line != NULL)
-+ {
-+ part_type = strtok (line, ":\t");
-+ part_object = strtok (NULL, ":\t");
-+ part_tag = strtok (NULL, ":\t");
-+ part_perms = strtok (NULL, ":\t");
-+
-+ foundline = 1;
-+ userpart = strtok (part_perms, ",\t");
-+
-+ if (strstr (userpart, muser))
-+ founduserpart = xstrdup (userpart);
-+ else
-+ {
-+ otheruserparts = xstrdup (userpart);
-+ otherslen = strlen (otheruserparts);
-+ }
-+
-+ while ((userpart = strtok (NULL, ",\t")) != NULL)
-+ {
-+ if (strncmp (userpart, muser, strlen (muser)) == 0)
-+ founduserpart = xstrdup (userpart);
-+ else
-+ {
-+ if (otheruserparts != NULL)
-+ {
-+ xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
-+ xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
-+ }
-+ else
-+ {
-+ otheruserparts = xstrdup (userpart);
-+ otherslen = strlen (otheruserparts);
-+ }
-+ }
-+ }
-+ }
-+
-+ wperms = make_perms (mperms, founduserpart, &errmsg);
-+ if (wperms == NULL)
-+ {
-+ if (errmsg)
-+ error (0, 0, "%s %s", filefullname, errmsg);
-+
-+ return (0);
-+ }
-+ else
-+ {
-+ cvs_output ("X ", 0);
-+ cvs_output (filefullname, 0);
-+ cvs_output ("\n", 0);
-+
-+ write_perms (muser, wperms, founduserpart, foundline,
-+ otheruserparts, "f", filefullname, tag, pos, finfo->repository);
-+ }
-+
-+ return (0);
-+}
-+
-+static Dtype
-+acl_dirproc (callerdat, dir, repos, update_dir, entries)
-+void *callerdat;
-+const char *dir;
-+const char *repos;
-+const char *update_dir;
-+List *entries;
-+{
-+ const char *drepository;
-+ char *founduserpart = NULL;
-+ char *newuserpart = NULL;
-+ char *otheruserparts = NULL;
-+ size_t otherslen = 0;
-+ int foundline = 0;
-+
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+ int linelen;
-+
-+ FILE *accessfp;
-+ char *part_type = NULL;
-+ char *part_object = NULL;
-+ char *part_tag = NULL;
-+ char *part_perms = NULL;
-+ char *wperms;
-+ int i = 0;
-+ char *userpart;
-+ int pos;
-+
-+ char *errmsg;
-+
-+ if (repos[0] == '\0')
-+ repos = Name_Repository (dir, NULL);
-+
-+ if (!acldir)
-+ return (0);
-+
-+ if (!access_allowed (NULL, repos, tag, 8, &line, &pos, 0))
-+ error (1,0,"You do not have admin rights on '%s'", Short_Repository (repos));
-+
-+ drepository = Short_Repository (repos);
-+
-+ if (line != NULL)
-+ {
-+ part_type = strtok (line, ":\t");
-+ part_object = strtok (NULL, ":\t");
-+ part_tag = strtok (NULL, ":\t");
-+ part_perms = strtok (NULL, ":\t");
-+
-+ foundline = 1;
-+ userpart = strtok (part_perms, ",\t");
-+
-+ if (strstr (userpart, muser))
-+ founduserpart = xstrdup (userpart);
-+ else
-+ {
-+ otheruserparts = xstrdup (userpart);
-+ otherslen = strlen (otheruserparts);
-+ }
-+
-+ while ((userpart = strtok (NULL, ",\t")) != NULL)
-+ {
-+ if (strncmp (userpart, muser, strlen (muser)) == 0)
-+ founduserpart = xstrdup (userpart);
-+ else
-+ {
-+ if (otheruserparts != NULL)
-+ {
-+ xrealloc_and_strcat (&otheruserparts, &otherslen, ",");
-+ xrealloc_and_strcat (&otheruserparts, &otherslen, userpart);
-+ }
-+ else
-+ {
-+ otheruserparts = xstrdup (userpart);
-+ otherslen = strlen (otheruserparts);
-+ }
-+ }
-+ }
-+ }
-+
-+ wperms = make_perms (mperms, founduserpart, &errmsg);
-+ if (wperms == NULL)
-+ {
-+ if (errmsg)
-+ error (0, 0, "%s %s", drepository, errmsg);
-+
-+ return (0);
-+ }
-+ else
-+ {
-+ if (defaultperms)
-+ {
-+ cvs_output ("X ", 0);
-+ cvs_output ("ALL", 0);
-+ cvs_output ("\n", 0);
-+ write_perms (muser, wperms, founduserpart, foundline,
-+ otheruserparts, "d", "ALL", tag, pos, drepository);//baris
-+
-+ }
-+ else
-+ {
-+ cvs_output ("X ", 0);
-+ cvs_output (drepository, 0);
-+ cvs_output ("\n", 0);
-+ write_perms (muser, wperms, founduserpart, foundline,
-+ otheruserparts, "d", drepository, tag, pos, drepository);//baris `repos`
-+ }
-+ }
-+
-+ return (0);
-+}
-+
-+/* Open CVSROOT/access or defined CVSACLFileLocation file. */
-+FILE *
-+open_accessfile (fmode, adir, fname)
-+char *fmode;
-+const char *adir;
-+char **fname;
-+{
-+ char *accessfile;
-+ FILE *accessfp;
-+
-+ if (!use_separate_acl_file_for_each_dir)
-+ {
-+ if (cvs_acl_file_location == NULL)
-+ {
-+ accessfile = xmalloc (strlen (current_parsed_root->directory)
-+ + sizeof (CVSROOTADM)
-+ + sizeof (CVSROOTADM_ACCESS)
-+ + 3);
-+
-+ strcpy (accessfile, current_parsed_root->directory);
-+ strcat (accessfile, "/");
-+ strcat (accessfile, CVSROOTADM);
-+ strcat (accessfile, "/");
-+ strcat (accessfile, CVSROOTADM_ACCESS);
-+ }
-+ else
-+ {
-+ accessfile = xmalloc (strlen (cvs_acl_file_location));
-+ strcpy (accessfile, cvs_acl_file_location);
-+ }
-+ }
-+ else
-+ {
-+ accessfile = xmalloc (strlen (current_parsed_root->directory)
-+ + strlen (adir)
-+ + strlen ("access")
-+ + 3);
-+
-+ strcpy (accessfile, current_parsed_root->directory);
-+ strcat (accessfile, "/");
-+ strcat (accessfile, adir);
-+ strcat (accessfile, "/");
-+ strcat (accessfile, "access");
-+ }
-+
-+ accessfp = CVS_FOPEN (accessfile, fmode);
-+
-+ if (accessfp == NULL)
-+ error (0, 0, "cannot open file: %s", accessfile);
-+
-+ if (fname != NULL)
-+ *fname = xstrdup (accessfile);
-+
-+ free (accessfile);
-+
-+ return (accessfp);
-+}
-+
-+/* Open /etc/group file if UseSystemGroups=yes in config file. */
-+/* Open CVSROOT/group file if UseCVSGroups=yes in config file. */
-+FILE *
-+open_groupfile (fmode)
-+char *fmode;
-+{
-+ char *groupfile;
-+ FILE *groupfp;
-+
-+ if (use_cvs_groups)
-+ {
-+ if (cvs_groups_file_location != NULL)
-+ {
-+ groupfile = xmalloc (strlen (cvs_groups_file_location));
-+ strcpy (groupfile, cvs_groups_file_location);
-+ }
-+ else
-+ {
-+ groupfile = xmalloc (strlen (current_parsed_root->directory)
-+ + sizeof (CVSROOTADM)
-+ + sizeof (CVSROOTADM_GROUP)
-+ + 3);
-+
-+ strcpy (groupfile, current_parsed_root->directory);
-+ strcat (groupfile, "/");
-+ strcat (groupfile, CVSROOTADM);
-+ strcat (groupfile, "/");
-+ strcat (groupfile, CVSROOTADM_GROUP);
-+ }
-+ }
-+
-+ else
-+ {
-+ return (NULL);
-+ }
-+
-+ groupfp = CVS_FOPEN (groupfile, "r");
-+
-+ if (groupfp == NULL)
-+ error (0, 0, "cannot open file: %s", groupfile);
-+
-+ free (groupfile);
-+
-+ return (groupfp);
-+}
-+
-+
-+/* Check whether given permissions are valid or not. */
-+/* Returns 1 if permissions are valid. */
-+/* Returns 0 if permissions are NOT valid. */
-+int
-+given_perms_valid (cperms)
-+char *cperms;
-+{
-+ int cperms_len;
-+ int retval;
-+ int index, i;
-+
-+ if (cperms[0] == '+' || cperms[0] == '-')
-+ index = 1;
-+ else
-+ index = 0;
-+
-+ cperms_len = strlen (cperms);
-+
-+ switch (cperms[index])
-+ {
-+ case 'x':
-+ if ((cperms_len - index) == 1 && cperms_len == 1)
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'n':
-+ if ((cperms_len - index) == 1 && cperms_len == 1)
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'p':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'a':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 'p')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'r':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'w':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'd')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 't':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 'w' || cperms[i] == 'c' || cperms[i] == 'd')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'c':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 't' || cperms[i] == 'w' || cperms[i] == 'd')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ case 'd':
-+ if ((cperms_len - index) == 1)
-+ retval = 1;
-+ else
-+ for (i = index + 1; i < cperms_len; i++)
-+ if (cperms[i] == 't' || cperms[i] == 'c' || cperms[i] == 'w')
-+ retval = 1;
-+ else
-+ retval = 0;
-+ break;
-+ default:
-+ retval = 0;
-+ break;
-+ }
-+ return (retval);
-+}
-+
-+char *
-+make_perms (perms, founduserpart, xerrmsg)
-+char *perms;
-+char *founduserpart;
-+char **xerrmsg;
-+{
-+ char *fperms;
-+ size_t perms_len;
-+ size_t fperms_len;
-+ char *retperms = NULL;
-+ char *xperms;
-+ int i, j;
-+ int err = 0;
-+ char *errmsg = NULL;
-+ size_t retperms_len = 1;
-+
-+ retperms = xmalloc (retperms_len);
-+ retperms[0] = '\0';
-+
-+ perms_len = strlen (perms);
-+
-+ if (perms[0] == '+' || perms[0] == '-')
-+ {
-+ if (founduserpart)
-+ {
-+ char *temp;
-+ temp = strtok (founduserpart, "!\t");
-+ fperms = strtok (NULL, "!\t");
-+ fperms_len = strlen (fperms);
-+
-+ if (strncmp (fperms, "x", 1) == 0)
-+ {
-+ err = 1;
-+ if (perms[0] == '+')
-+ *xerrmsg = xstrdup ("cannot add default permission 'x'");
-+ else
-+ *xerrmsg = xstrdup ("cannot remove default permission 'x'");
-+ }
-+
-+ for (i = 1; i < perms_len && !err; i++)
-+ {
-+ switch (perms[i])
-+ {
-+ case 'n':
-+ err = 1;
-+ break;
-+ case 'p':
-+ if (perms[0] == '+')
-+ fperms = xstrdup ("p");
-+ else if (perms[0] == '-')
-+ {
-+ fperms_len = 1;
-+ fperms = xmalloc (fperms_len);
-+ fperms[0] = '\0';
-+ }
-+ break;
-+ case 'a':
-+ for (j = 0; j < fperms_len; j++)
-+ {
-+ if (fperms[j] == 'p')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has admin rights, cannot use +/- permissions");
-+ }
-+ else if (fperms[j] == 'a' && perms[0] == '+')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user already has all ('a') permission");
-+ }
-+ else if (fperms[j] != 'a' && perms[0] == '-')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user does not have all ('a') permission");
-+ }
-+ }
-+ if (perms[0] == '+')
-+ {
-+ fperms = xstrdup ("a");
-+ fperms_len = strlen (fperms);
-+ }
-+ else if (perms[0] == '-')
-+ {
-+ fperms_len = 1;
-+ fperms = xmalloc (fperms_len);
-+ fperms[0] = '\0';
-+ }
-+
-+ break;
-+ case 'r':
-+ for (i = 0; i < fperms_len; i++)
-+ {
-+ if (fperms[i] == 'n' && perms[0] == '+')
-+ {
-+ fperms = xstrdup ("r");
-+ fperms_len = strlen (fperms);
-+ }
-+ else if (fperms[i] == 'r' && perms[0] == '-')
-+ {
-+ fperms_len = 1;
-+ fperms = xmalloc (fperms_len);
-+ fperms[0] = '\0';
-+ }
-+ else if (perms[0] == '-')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has other permissions, cannot remove read ('r') permission");
-+ }
-+ else
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has other permissions, cannot remove read ('r') permission");
-+ }
-+ }
-+ break;
-+ case 'w':
-+ {
-+ char *tempfperms;
-+ size_t tempfperms_len = 1;
-+
-+ tempfperms = xmalloc (tempfperms_len);
-+ tempfperms[0] = '\0';
-+
-+ for (j = 0; j < fperms_len; j++)
-+ {
-+ if (fperms[j] == 't' || fperms[j] == 'c' || fperms[j] == 'd')
-+ {
-+ char *temp;
-+ temp = xmalloc (2);
-+ temp[0] = fperms[j];
-+ temp[1] = '\0';
-+
-+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
-+ free (temp);
-+ }
-+ else if (fperms[j] == 'a' || fperms[j] == 'p')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- write permissions");
-+ }
-+ else if (fperms[j] == 'n' || fperms[j] == 'r')
-+ {
-+ if (perms[0] == '-')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user does not have write ('w') permission");
-+ }
-+ }
-+ }
-+
-+ fperms = xstrdup (tempfperms);
-+ fperms_len = strlen (fperms);
-+ free (tempfperms);
-+
-+ if (perms[0] == '+')
-+ {
-+ xrealloc_and_strcat (&fperms, &fperms_len, "w");
-+ }
-+ }
-+ break;
-+ case 't':
-+ {
-+ char *tempfperms;
-+ size_t tempfperms_len = 1;
-+
-+ tempfperms = xmalloc (tempfperms_len);
-+ tempfperms[0] = '\0';
-+
-+ for (j = 0; j < fperms_len; j++)
-+ {
-+ if (fperms[j] == 'w' || fperms[j] == 'c' || fperms[j] == 'd')
-+ {
-+ char *temp;
-+ temp = xmalloc (2);
-+ temp[0] = fperms[j];
-+ temp[1] = '\0';
-+
-+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
-+ free (temp);
-+ }
-+ else if (fperms[j] == 'a' || fperms[j] == 'p')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- tag permissions");
-+ }
-+ else if (fperms[i] == 'n' || fperms[i] == 'r')
-+ {
-+ if (perms[0] == '-')
-+ *xerrmsg = xstrdup ("user does not have tag ('t') permission");
-+ }
-+ }
-+
-+ fperms = xstrdup (tempfperms);
-+ fperms_len = strlen (fperms);
-+ free (tempfperms);
-+
-+ if (perms[0] == '+')
-+ {
-+ xrealloc_and_strcat (&fperms, &fperms_len, "t");
-+ }
-+ }
-+ break;
-+ case 'c':
-+ {
-+ char *tempfperms;
-+ size_t tempfperms_len = 1;
-+
-+ tempfperms = xmalloc (tempfperms_len);
-+ tempfperms[0] = '\0';
-+
-+ for (j = 0; j < fperms_len; j++)
-+ {
-+ if (fperms[j] == 'w' || fperms[j] == 't' || fperms[j] == 'd')
-+ {
-+ char *temp;
-+ temp = xmalloc (2);
-+ temp[0] = fperms[j];
-+ temp[1] = '\0';
-+
-+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
-+ free (temp);
-+ }
-+ else if (fperms[j] == 'a' || fperms[j] == 'p')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- create permissions");
-+ }
-+ else if (fperms[i] == 'n' || fperms[i] == 'r')
-+ {
-+ if (perms[0] == '-')
-+ err = 1;
-+ *xerrmsg = xstrdup ("user does not have create ('c') permission");
-+ }
-+
-+ }
-+
-+ fperms = xstrdup (tempfperms);
-+ fperms_len = strlen (fperms);
-+ free (tempfperms);
-+
-+ if (perms[0] == '+')
-+ {
-+ xrealloc_and_strcat (&fperms, &fperms_len, "c");
-+ }
-+ }
-+ break;
-+ case 'd':
-+ {
-+ char *tempfperms;
-+ size_t tempfperms_len = 1;
-+
-+ tempfperms = xmalloc (tempfperms_len);
-+ tempfperms[0] = '\0';
-+
-+ for (j = 0; j < fperms_len; j++)
-+ {
-+ if (fperms[j] == 'w' || fperms[j] == 'c' || fperms[j] == 't')
-+ {
-+ char *temp;
-+ temp = xmalloc (2);
-+ temp[0] = fperms[j];
-+ temp[1] = '\0';
-+
-+ xrealloc_and_strcat (&tempfperms, &tempfperms_len, temp);
-+ free (temp);
-+ }
-+ else if (fperms[j] == 'a' || fperms[j] == 'p')
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup ("user has higher permissions, cannot use +/- delete permissions");
-+ }
-+ else if (fperms[i] == 'n' || fperms[i] == 'r')
-+ {
-+ if (perms[0] == '-')
-+ err = 1;
-+ *xerrmsg = xstrdup ("user does not have delete ('d') permission");
-+ }
-+ }
-+
-+ fperms = xstrdup (tempfperms);
-+ fperms_len = strlen (fperms);
-+ free (tempfperms);
-+
-+ if (perms[0] == '+')
-+ {
-+ xrealloc_and_strcat (&fperms, &fperms_len, "d");
-+ }
-+ }
-+ break;
-+ default:
-+ err = 1;
-+ *xerrmsg = xstrdup ("error in 'access' file format");
-+ break;
-+ }
-+ if (fperms[0] == '\0')
-+ retperms = xstrdup ("none");
-+ else
-+ retperms = xstrdup (fperms);
-+ }
-+ }
-+ else
-+ {
-+ err = 1;
-+ *xerrmsg = xstrdup("user is not given any permissions to remove/add");
-+ }
-+ }
-+
-+ else
-+ {
-+ retperms = xstrdup (perms);
-+ }
-+
-+ if (err)
-+ return (NULL);
-+ else
-+ return (retperms);
-+}
-+
-+int
-+write_perms (user, perms, founduserpart, foundline, otheruserparts,
-+ part_type, part_object, part_tag, pos, arepos)
-+char *user;
-+char *perms;
-+char *founduserpart;
-+int foundline;
-+char *otheruserparts;
-+char *part_type;
-+char *part_object;
-+char *part_tag;
-+int pos;
-+char *arepos;
-+{
-+ char *accessfile;
-+ char *tmpaccessout;
-+ FILE *accessfpin;
-+ FILE *accessfpout;
-+
-+ char *newline = NULL;
-+ size_t newlinelen = 1;
-+
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+
-+ newline = xmalloc (newlinelen);
-+ newline[0] = '\0';
-+
-+ if (!cvs_casecmp (part_tag, "ALL"))
-+ part_tag = xstrdup ("ALL");
-+
-+ xrealloc_and_strcat (&newline, &newlinelen, part_type);
-+ xrealloc_and_strcat (&newline, &newlinelen, ":");
-+ xrealloc_and_strcat (&newline, &newlinelen, part_object);
-+ xrealloc_and_strcat (&newline, &newlinelen, ":");
-+ xrealloc_and_strcat (&newline, &newlinelen, part_tag);
-+ xrealloc_and_strcat (&newline, &newlinelen, ":");
-+
-+ if (strncmp (perms, "none", 4) != 0)
-+ {
-+ xrealloc_and_strcat (&newline, &newlinelen, user);
-+ xrealloc_and_strcat (&newline, &newlinelen, "!");
-+ xrealloc_and_strcat (&newline, &newlinelen, perms);
-+ if (otheruserparts != NULL)
-+ xrealloc_and_strcat (&newline, &newlinelen, ",");
-+ }
-+
-+ if (otheruserparts != NULL)
-+ {
-+ if (otheruserparts[strlen (otheruserparts) - 1] == '\n')
-+ otheruserparts[strlen (otheruserparts) - 1] = '\0';
-+
-+ xrealloc_and_strcat (&newline, &newlinelen, otheruserparts);
-+ }
-+
-+ xrealloc_and_strcat (&newline, &newlinelen, ":");
-+
-+ if (foundline)
-+ {
-+ accessfpout = cvs_temp_file (&tmpaccessout);
-+ accessfpin = open_accessfile ("r", arepos, &accessfile);
-+
-+ while (getline (&line, &line_allocated, accessfpin) >= 0)
-+ {
-+ if (pos != ftell (accessfpin))
-+ {
-+ if (fprintf (accessfpout, line) < 0)
-+ error (1, errno, "writing temporary file: %s", tmpaccessout);
-+ }
-+ else
-+ {
-+ if (fprintf (accessfpout, "%s\n", newline) < 0)
-+ error (1, errno, "writing temporary file: %s", tmpaccessout);
-+ }
-+
-+ }
-+ if (fclose (accessfpin) == EOF)
-+ error (1, errno, "cannot close access file: %s", accessfile);
-+
-+ if (fclose (accessfpout) == EOF)
-+ error (1, errno, "cannot close temporary file: %s", tmpaccessout);
-+
-+ if (CVS_UNLINK (accessfile) < 0)
-+ error (0, errno, "cannot remove %s", accessfile);
-+
-+ copy_file (tmpaccessout, accessfile);
-+
-+ if (CVS_UNLINK (tmpaccessout) < 0)
-+ error (0, errno, "cannot remove temporary file: %s", tmpaccessout);
-+ }
-+ else
-+ {
-+ accessfpout = open_accessfile ("r+", arepos, &accessfile);
-+
-+ if (accessfpout == NULL)
-+ {
-+ if (existence_error (errno))
-+ {
-+ accessfpout = open_accessfile ("w+", arepos, &accessfile);
-+ }
-+ }
-+ else {
-+ if (fseek (accessfpout, 0, 2) != 0)
-+ error (1, errno, "cannot fseek access file: %s", accessfile);
-+ }
-+
-+ if (fprintf (accessfpout, "%s\n", newline) < 0)
-+ error (1, errno, "writing access file: %s", accessfile);
-+
-+ if (fclose (accessfpout) == EOF)
-+ error (1, errno, "cannot close access file: %s", accessfile);
-+ }
-+
-+ free (newline);
-+
-+ chmod(accessfile, 0644);
-+
-+ return (0);
-+}
-+
-+
-+static int
-+acllist_fileproc (callerdat, finfo)
-+void *callerdat;
-+struct file_info *finfo;
-+{
-+
-+ char *filefullname;
-+ const char *frepository;
-+ char *line = NULL;
-+ int pos;
-+
-+ if (!aclfile)
-+ return (0);
-+
-+ frepository = Short_Repository (finfo->repository);
-+
-+ filefullname = xmalloc (strlen (frepository)
-+ + strlen (finfo->file)
-+ + 2);
-+ strcpy (filefullname, frepository);
-+ strcat (filefullname, "/");
-+ strcat (filefullname, finfo->file);
-+
-+ if (!access_allowed (finfo->file, finfo->repository, tag, 5, &line, &pos, 0))
-+ error (1,0,"You do not have admin rights on '%s'", frepository);
-+
-+ acllist_print (line, filefullname);
-+
-+ return (0);
-+}
-+
-+static Dtype
-+acllist_dirproc (callerdat, dir, repos, update_dir, entries)
-+void *callerdat;
-+const char *dir;
-+const char *repos;
-+const char *update_dir;
-+List *entries;
-+{
-+
-+ char *line = NULL;
-+ const char *drepository;
-+ int pos;
-+
-+ if (repos[0] == '\0')
-+ repos = Name_Repository (dir, NULL);
-+
-+ if (!acldir)
-+ return (0);
-+
-+ drepository = Short_Repository (repos);
-+
-+ if (!access_allowed (NULL, repos, tag, 5, &line, &pos, 0))
-+ error (1, 0, "You do not have admin rights on '%s'", drepository);
-+
-+ acllist_print (line, drepository);
-+
-+ return (0);
-+}
-+
-+
-+void
-+acllist_print (line, obj)
-+char *line;
-+const char *obj;
-+{
-+ char *temp;
-+ char *temp2;
-+ int x;
-+ int c = 0;
-+
-+ char *printedusers[255];
-+ printedusers[0] = NULL;
-+
-+ if (line != NULL)
-+ {
-+ temp = strtok (line, ":\t");
-+
-+ if (acldir)
-+ cvs_output ("d ", 0);
-+ else if (aclfile)
-+ cvs_output ("f ", 0);
-+
-+ temp = strtok (NULL, ":\t");
-+
-+ cvs_output(obj, 0);
-+ cvs_output (" | ", 0);
-+
-+ temp = strtok (NULL, ":\t");
-+ cvs_output (temp, 0);
-+ cvs_output (" | ", 0);
-+
-+ while ((temp = strtok (NULL, "!\t")) != NULL)
-+ {
-+ if (strncmp (temp, ":", 1) == 0)
-+ break;
-+
-+ if (strcmp (temp, "ALL") == 0)
-+ {
-+ temp = strtok (NULL, ",\t");
-+ continue;
-+ }
-+
-+ cvs_output (temp, 0);
-+ cvs_output (":", 0);
-+
-+ while (printedusers[c] != NULL)
-+ c++;
-+
-+ printedusers[c] = xstrdup (temp);
-+ c++;
-+ printedusers[c] = NULL;
-+
-+ temp = strtok (NULL, ",\t");
-+
-+ if (temp != NULL && temp[strlen (temp) - 2] == ':')
-+ temp[strlen (temp) - 2] = '\0';
-+
-+ cvs_output (temp, 0);
-+ cvs_output (" ", 0);
-+ }
-+
-+ if (default_perms_object)
-+ {
-+ cvs_output ("| defaults ", 0);
-+ cvs_output ("ALL:", 0);
-+ cvs_output (default_perms_object, 0);
-+ }
-+ else if (default_part_perms_accessfile)
-+ {
-+ size_t i;
-+ i = strlen (default_part_perms_accessfile);
-+ xrealloc_and_strcat (&default_part_perms_accessfile, &i, ",");
-+
-+ free(line);
-+ line = xstrdup(default_part_perms_accessfile);
-+
-+ cvs_output ("| defaults ", 0);
-+
-+ temp = strtok (line, "!\t");
-+ cvs_output (temp, 0);
-+ cvs_output (":", 0);
-+
-+ temp = strtok (NULL, ",\t");
-+
-+ cvs_output (temp, 0);
-+ cvs_output (" ", 0);
-+
-+ while ((temp = strtok (NULL, "!\t")) != NULL)
-+ {
-+ int printed = 0;
-+ int c2 = 0;
-+ while (printedusers[c2] != NULL && printed == 0)
-+ {
-+ if (strcmp (printedusers[c2], temp) == 0)
-+ {
-+ printed = 1;
-+ break;
-+ }
-+ c2++;
-+ }
-+
-+ if (printed == 0)
-+ {
-+ cvs_output (temp, 0);
-+ cvs_output (":", 0);
-+ }
-+
-+ temp = strtok (NULL, ",\t");
-+
-+ if (temp[strlen (temp) - 2] == ':')
-+ temp[strlen (temp) - 2] = '\0';
-+
-+ if (printed == 0)
-+ {
-+ cvs_output (temp, 0);
-+ cvs_output (" ", 0);
-+ }
-+ }
-+ }
-+ else if (cvs_acl_default_permissions)
-+ {
-+ cvs_output ("| defaults ", 0);
-+ cvs_output ("ALL: ", 0);
-+ cvs_output (cvs_acl_default_permissions, 0);
-+ }
-+
-+ cvs_output ("\n", 0);
-+
-+ }
-+ else
-+ {
-+ if (acldir)
-+ cvs_output ("d ", 0);
-+ else if (aclfile)
-+ cvs_output ("f ", 0);
-+ cvs_output (obj, 0);
-+ cvs_output (" | ", 0);
-+ cvs_output (tag, 0);
-+ cvs_output (" | ", 0);
-+
-+ if (default_perms_object)
-+ {
-+ cvs_output ("| defaults ", 0);
-+ cvs_output ("ALL:", 0);
-+ cvs_output (default_perms_object, 0);
-+ cvs_output ("\n", 0);
-+ }
-+ else if (default_part_perms_accessfile)
-+ {
-+ free(line);
-+ line = xstrdup(default_part_perms_accessfile);
-+
-+ cvs_output ("| defaults ", 0);
-+
-+ temp = strtok (line, "!\t");
-+ cvs_output (temp, 0);
-+ cvs_output (":", 0);
-+
-+ temp = strtok (NULL, ",\t");
-+
-+ if (temp[strlen (temp) - 2] == ':')
-+ temp[strlen (temp) - 2] = '\0';
-+
-+ cvs_output (temp, 0);
-+ cvs_output (" ", 0);
-+
-+ while ((temp = strtok (NULL, "!\t")) != NULL)
-+ {
-+ cvs_output (temp, 0);
-+ cvs_output (":", 0);
-+
-+ temp = strtok (NULL, ",\t");
-+
-+ if (temp[strlen (temp) - 2] == ':')
-+ temp[strlen (temp) - 2] = '\0';
-+
-+ cvs_output (temp, 0);
-+ cvs_output (" ", 0);
-+ }
-+ cvs_output ("\n", 0);
-+ }
-+ else if (cvs_acl_default_permissions)
-+ {
-+ cvs_output ("| defaults ", 0);
-+ cvs_output ("ALL: ", 0);
-+ cvs_output (cvs_acl_default_permissions, 0);
-+ cvs_output ("\n", 0);
-+ }
-+ else
-+ cvs_output ("default:p (no perms)\n", 0);
-+ }
-+
-+}
-diff -urN cvs-1.11.19.orig/src/add.c cvs-1.11.19/src/add.c
---- cvs-1.11.19.orig/src/add.c 2005-01-31 23:09:18.000000000 +0100
-+++ cvs-1.11.19/src/add.c 2005-03-14 19:55:09.000000000 +0100
-@@ -405,6 +405,24 @@
- }
- else
- {
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo.file, repository, vers->tag, 6,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo.repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo.repository), finfo.file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
- /* There is a user file, so build the entry for it */
- if (build_entry (repository, finfo.file, vers->options,
- message, entries, vers->tag) != 0)
-@@ -679,6 +697,26 @@
- && isdir (finfo.file)
- && !wrap_name_has (finfo.file, WRAP_TOCVS))
- {
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (NULL, repository, NULL, 6,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo.repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo.repository), finfo.file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- err += add_directory (&finfo);
- }
- else
-diff -urN cvs-1.11.19.orig/src/admin.c cvs-1.11.19/src/admin.c
---- cvs-1.11.19.orig/src/admin.c 2005-01-31 23:09:57.000000000 +0100
-+++ cvs-1.11.19/src/admin.c 2005-03-14 19:55:09.000000000 +0100
-@@ -566,6 +566,25 @@
-
- vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, NULL, 2,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- version = vers->vn_user;
- if (version != NULL && strcmp (version, "0") == 0)
- {
-diff -urN cvs-1.11.19.orig/src/annotate.c cvs-1.11.19/src/annotate.c
---- cvs-1.11.19.orig/src/annotate.c 2005-01-31 23:10:09.000000000 +0100
-+++ cvs-1.11.19/src/annotate.c 2005-03-14 19:55:09.000000000 +0100
-@@ -281,6 +281,25 @@
- if (version == NULL)
- return 0;
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, version, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- /* Distinguish output for various files if we are processing
- several files. */
- cvs_outerr ("\nAnnotations for ", 0);
-diff -urN cvs-1.11.19.orig/src/commit.c cvs-1.11.19/src/commit.c
---- cvs-1.11.19.orig/src/commit.c 2005-01-31 23:11:19.000000000 +0100
-+++ cvs-1.11.19/src/commit.c 2005-03-14 19:55:09.000000000 +0100
-@@ -1304,6 +1304,34 @@
- return 0;
-
- ci = p->data;
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ int whichperm;
-+ if (ci->status == T_MODIFIED)
-+ whichperm = 3;
-+ else if (ci->status == T_ADDED)
-+ whichperm = 6;
-+ else if (ci->status == T_REMOVED)
-+ whichperm = 7;
-+
-+ if (!access_allowed (finfo->file, finfo->repository, ci->tag, whichperm,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- if (ci->status == T_MODIFIED)
- {
- if (finfo->rcs == NULL)
-diff -urN cvs-1.11.19.orig/src/cvs.h cvs-1.11.19/src/cvs.h
---- cvs-1.11.19.orig/src/cvs.h 2005-03-14 19:49:29.000000000 +0100
-+++ cvs-1.11.19/src/cvs.h 2005-03-14 19:55:09.000000000 +0100
-@@ -200,6 +200,11 @@
- #define CVSROOTADM_PASSWD "passwd"
- #define CVSROOTADM_CONFIG "config"
-
-+/* cvsacl patch */
-+#define CVSROOTADM_ACLCONFIG "aclconfig"
-+#define CVSROOTADM_ACCESS "access"
-+#define CVSROOTADM_GROUP "group"
-+
- #define CVSNULLREPOS "Emptydir" /* an empty directory */
-
- /* Other CVS file names */
-@@ -572,6 +577,18 @@
- /* LockDir setting from CVSROOT/config. */
- extern char *lock_dir;
-
-+/* cvsacl patch */
-+/* ACL Patch settings from CVSROOT/config */
-+extern int use_cvs_acl;
-+extern char *cvs_acl_default_permissions;
-+extern int use_cvs_groups;
-+extern int use_system_groups;
-+extern int use_separate_acl_file_for_each_dir;
-+extern char *cvs_acl_file_location;
-+extern char *cvs_groups_file_location;
-+extern char *cvs_server_run_as;
-+extern int stop_at_first_permission_denied;
-+
- void Scratch_Entry PROTO((List * list, const char *fname));
- void ParseTag PROTO((char **tagp, char **datep, int *nonbranchp));
- void WriteTag PROTO ((const char *dir, const char *tag, const char *date,
-@@ -867,6 +884,10 @@
- int editors PROTO ((int argc, char **argv));
- int watchers PROTO ((int argc, char **argv));
- extern int annotate PROTO ((int argc, char **argv));
-+
-+/* cvsacl patch */
-+extern int cvsacl PROTO ((int argc, char **argv));
-+
- extern int add PROTO ((int argc, char **argv));
- extern int admin PROTO ((int argc, char **argv));
- extern int checkout PROTO ((int argc, char **argv));
-diff -urN cvs-1.11.19.orig/src/diff.c cvs-1.11.19/src/diff.c
---- cvs-1.11.19.orig/src/diff.c 2005-01-31 23:12:09.000000000 +0100
-+++ cvs-1.11.19/src/diff.c 2005-03-14 19:55:09.000000000 +0100
-@@ -479,6 +479,43 @@
- {
- /* Skip all the following checks regarding the user file; we're
- not using it. */
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (diff_rev1)
-+ {
-+ if (!access_allowed (NULL, finfo->repository, diff_rev1, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+ if (diff_rev2)
-+ {
-+ if (!access_allowed (NULL, finfo->repository, diff_rev2, 5))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+ }
-+#endif
-+
- }
- else if (vers->vn_user == NULL)
- {
-@@ -832,6 +869,42 @@
- if (!isdir (dir))
- return (R_SKIP_ALL);
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (diff_rev1)
-+ {
-+ if (!access_allowed (NULL, update_dir, diff_rev1, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (update_dir));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (update_dir), update_dir);
-+
-+ return (0);
-+ }
-+ }
-+ if (diff_rev2)
-+ {
-+ if (!access_allowed (NULL, update_dir, diff_rev2, 5))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (update_dir));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (update_dir), update_dir);
-+
-+ return (0);
-+ }
-+ }
-+ }
-+#endif
-+
- if (!quiet)
- error (0, 0, "Diffing %s", update_dir);
- return (R_PROCESS);
-diff -urN cvs-1.11.19.orig/src/import.c cvs-1.11.19/src/import.c
---- cvs-1.11.19.orig/src/import.c 2005-01-31 23:13:00.000000000 +0100
-+++ cvs-1.11.19/src/import.c 2005-03-14 19:55:09.000000000 +0100
-@@ -319,6 +319,20 @@
- error (1, 0, "attempt to import the repository");
- }
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (NULL, repository, argv[1], 6, NULL, NULL, 1))
-+ {
-+ error (stop_at_first_permission_denied, 0, "permission denied for %s",
-+ Short_Repository (repository));
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- /*
- * Make all newly created directories writable. Should really use a more
- * sophisticated security mechanism here.
-diff -urN cvs-1.11.19.orig/src/log.c cvs-1.11.19/src/log.c
---- cvs-1.11.19.orig/src/log.c 2005-02-03 15:50:51.000000000 +0100
-+++ cvs-1.11.19/src/log.c 2005-03-14 19:55:09.000000000 +0100
-@@ -853,6 +853,25 @@
- return 1;
- }
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, NULL, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- if (log_data->sup_header || !log_data->nameonly)
- {
-
-diff -urN cvs-1.11.19.orig/src/main.c cvs-1.11.19/src/main.c
---- cvs-1.11.19.orig/src/main.c 2005-03-14 19:49:29.000000000 +0100
-+++ cvs-1.11.19/src/main.c 2005-03-14 19:55:09.000000000 +0100
-@@ -102,6 +102,10 @@
- } cmds[] =
-
- {
-+ /* cvsacl patch */
-+ { "acl", NULL, NULL, cvsacl, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
-+ { "racl", NULL, NULL, cvsacl, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
-+
- { "add", "ad", "new", add, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "admin", "adm", "rcs", admin, CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
- { "annotate", "ann", NULL, annotate, CVS_CMD_USES_WORK_DIR },
-@@ -968,6 +972,9 @@
- if we didn't, then there would be no way to check in a new
- CVSROOT/config file to fix the broken one! */
- parse_config (current_parsed_root->directory);
-+
-+ /* cvsacl patch */
-+ parse_aclconfig (current_parsed_root->directory);
- }
-
- #ifdef CLIENT_SUPPORT
-diff -urN cvs-1.11.19.orig/src/mkmodules.c cvs-1.11.19/src/mkmodules.c
---- cvs-1.11.19.orig/src/mkmodules.c 2005-01-31 23:14:17.000000000 +0100
-+++ cvs-1.11.19/src/mkmodules.c 2005-03-14 19:55:09.000000000 +0100
-@@ -316,6 +316,44 @@
- NULL
- };
-
-+/* cvsacl patch */
-+static const char *const aclconfig_contents[] = {
-+ "# Set `UseCVSACL' to yes to use CVSACL feature.\n",
-+ "UseCVSACL=yes\n",
-+ "\n",
-+ "# Default CVSACL Permission to use.\n",
-+ "#CVSACLDefaultPermissions=p\n",
-+ "\n",
-+ "# Default file location for CVS ACL file (access) is CVSROOT/access.\n",
-+ "# If you want to use a different location, define it below.\n",
-+ "#CVSACLFileLocation=/path/to/cvs/access\n",
-+ "\n",
-+ "# Set `UseSystemGroups' to yes to use system group definitions (/etc/group).\n",
-+ "UseSystemGroups=yes\n",
-+ "\n",
-+ "# Set `UseCVSGroups' to yes to use another group file.\n",
-+ "#UseCVSGroups=yes\n",
-+ "\n",
-+ "# Default file location for CVS groups file is CVSROOT/group.\n",
-+ "# If you want to use a different location, define it below.\n",
-+ "#CVSGroupsFileLocation=/path/to/cvs/group\n",
-+ "\n",
-+ "# Set UseSeparateACLFileForEachDir to yes in order to use a\n",
-+ "# separate 'access' file for each directory.\n",
-+ "# This increased the performance if you have really big repository.\n",
-+ "#UseSeparateACLFileForEachDir=no\n",
-+ "\n",
-+ "# If StopAtFirstPermissionDenied is set to yes\n",
-+ "# operation will stop at first permission denied message.\n",
-+ "# Default is no.\n",
-+ "#StopAtFirstPermissionDenied=no\n",
-+ "\n",
-+ "# Set CVSServerRunAsUser to a system user, in order CVS server\n",
-+ "# to run as.\n",
-+ "#CVSServerRunAsUser=runascvsuser",
-+ NULL
-+};
-+
- static const struct admin_file filelist[] = {
- {CVSROOTADM_LOGINFO,
- "no logging of 'cvs commit' messages is done without a %s file",
-@@ -378,7 +416,12 @@
- {CVSROOTADM_CONFIG,
- "a %s file configures various behaviors",
- config_contents},
-- {NULL, NULL, NULL}
-+
-+ /* cvsacl patch */
-+ {CVSROOTADM_ACLCONFIG,
-+ "a %s file configures Access Control List behaviors",
-+ aclconfig_contents},
-+ {NULL, NULL, NULL}
- };
-
- /* Rebuild the checked out administrative files in directory DIR. */
-@@ -962,6 +1005,26 @@
- because xchmod() is too shy. */
- chmod (info, 0666);
- }
-+
-+ /* cvsacl patch */
-+ /* Make an empty 'CVSROOT/access' file */
-+ strcpy (info, adm);
-+ strcat (info, "/");
-+ strcat (info, CVSROOTADM_ACCESS);
-+ if (!isfile (info))
-+ {
-+ FILE *fp;
-+
-+ fp = open_file (info, "w");
-+ if (fputs ("# CVS ACL definitions file. DO NOT EDIT MANUALLY\n",
-+ fp) < 0)
-+ error (1, errno, "cannot write %s", info);
-+
-+ if (fclose (fp) < 0)
-+ error (1, errno, "cannot close %s", info);
-+
-+ chmod (info, 0644);
-+ }
-
- /* Make an empty val-tags file to prevent problems creating it later. */
- strcpy (info, adm);
-diff -urN cvs-1.11.19.orig/src/parseinfo.c cvs-1.11.19/src/parseinfo.c
---- cvs-1.11.19.orig/src/parseinfo.c 2005-01-31 23:14:54.000000000 +0100
-+++ cvs-1.11.19/src/parseinfo.c 2005-03-14 19:55:09.000000000 +0100
-@@ -453,3 +453,192 @@
- free (line);
- return -1;
- }
-+/* cvsacl patch */
-+int
-+parse_aclconfig (cvsroot)
-+ char *cvsroot;
-+{
-+ char *infopath;
-+ FILE *fp_info;
-+ char *line = NULL;
-+ size_t line_allocated = 0;
-+ size_t len;
-+ char *p;
-+ /* FIXME-reentrancy: If we do a multi-threaded server, this would need
-+ to go to the per-connection data structures. */
-+ static int parsed = 0;
-+
-+ /* Authentication code and serve_root might both want to call us.
-+ Let this happen smoothly. */
-+ if (parsed)
-+ return 0;
-+ parsed = 1;
-+
-+ infopath = xmalloc (strlen (cvsroot)
-+ + sizeof (CVSROOTADM_ACLCONFIG)
-+ + sizeof (CVSROOTADM)
-+ + 10);
-+ if (infopath == NULL)
-+ {
-+ error (0, 0, "out of memory; cannot allocate infopath");
-+ goto error_return;
-+ }
-+
-+ strcpy (infopath, cvsroot);
-+ strcat (infopath, "/");
-+ strcat (infopath, CVSROOTADM);
-+ strcat (infopath, "/");
-+ strcat (infopath, CVSROOTADM_ACLCONFIG);
-+
-+ fp_info = CVS_FOPEN (infopath, "r");
-+ if (fp_info == NULL)
-+ {
-+ /* If no file, don't do anything special. */
-+ if (!existence_error (errno))
-+ {
-+ /* Just a warning message; doesn't affect return
-+ value, currently at least. */
-+ error (0, errno, "cannot open %s", infopath);
-+ }
-+ free (infopath);
-+ return 0;
-+ }
-+
-+ while (getline (&line, &line_allocated, fp_info) >= 0)
-+ {
-+ /* Skip comments. */
-+ if (line[0] == '#')
-+ continue;
-+
-+ len = strlen (line) - 1;
-+ if (line[len] == '\n')
-+ line[len] = '\0';
-+
-+ /* Skip blank lines. */
-+ if (line[0] == '\0')
-+ continue;
-+
-+ /* The first '=' separates keyword from value. */
-+ p = strchr (line, '=');
-+ if (p == NULL)
-+ {
-+ /* Probably should be printing line number. */
-+ error (0, 0, "syntax error in %s: line '%s' is missing '='",
-+ infopath, line);
-+ goto error_return;
-+ }
-+
-+ *p++ = '\0';
-+
-+ if (strcmp (line, "UseCVSACL") == 0)
-+ {
-+ if (strcmp (p, "no") == 0)
-+ use_cvs_acl = 0;
-+ else if (strcmp (p, "yes") == 0)
-+ use_cvs_acl = 1;
-+ else
-+ {
-+ error (0, 0, "unrecognized value '%s' for UseCVSACL", p);
-+ goto error_return;
-+ }
-+ }
-+ else if (strcmp (line, "UseSeparateACLFileForEachDir") == 0)
-+ {
-+ if (strcmp (p, "no") == 0)
-+ use_separate_acl_file_for_each_dir = 0;
-+ else if (strcmp (p, "yes") == 0)
-+ use_separate_acl_file_for_each_dir = 1;
-+ else
-+ {
-+ error (0, 0, "unrecognized value '%s' for UseSeparateACLFileForEachDir", p);
-+ goto error_return;
-+ }
-+ }
-+ else if (strcmp (line, "StopAtFirstPermissionDenied") == 0)
-+ {
-+ if (strcmp (p, "no") == 0)
-+ stop_at_first_permission_denied = 0;
-+ else if (strcmp (p, "yes") == 0)
-+ stop_at_first_permission_denied = 1;
-+ else
-+ {
-+ error (0, 0, "unrecognized value '%s' for StopAtFirstPermissionDenied", p);
-+ goto error_return;
-+ }
-+ }
-+ else if (strcmp (line, "CVSACLDefaultPermissions") == 0)
-+ {
-+ if (cvs_acl_default_permissions != NULL)
-+ free (cvs_acl_default_permissions);
-+ if (!given_perms_valid (p))
-+ error (1,0,"Invalid CVS ACL Default Permissions: '%s' in CVSROOT/aclconfig", p);
-+ cvs_acl_default_permissions = xstrdup (p);
-+ }
-+ else if (strcmp (line, "UseCVSGroups") == 0)
-+ {
-+ if (strcmp (p, "no") == 0)
-+ use_cvs_groups = 0;
-+ else if (strcmp (p, "yes") == 0)
-+ use_cvs_groups = 1;
-+ else
-+ {
-+ error (0, 0, "unrecognized value '%s' for UseCVSGroups", p);
-+ goto error_return;
-+ }
-+ }
-+ else if (strcmp (line, "UseSystemGroups") == 0)
-+ {
-+ if (strcmp (p, "no") == 0)
-+ use_system_groups = 0;
-+ else if (strcmp (p, "yes") == 0)
-+ use_system_groups = 1;
-+ else
-+ {
-+ error (0, 0, "unrecognized value '%s' for UseSystemGroups", p);
-+ goto error_return;
-+ }
-+ }
-+ else if (strcmp (line, "CVSACLFileLocation") == 0)
-+ {
-+ if (cvs_acl_file_location != NULL)
-+ free (cvs_acl_file_location);
-+ cvs_acl_file_location = xstrdup (p);
-+ }
-+ else if (strcmp (line, "CVSGroupsFileLocation") == 0)
-+ {
-+ if (cvs_groups_file_location != NULL)
-+ free (cvs_groups_file_location);
-+ cvs_groups_file_location = xstrdup (p);
-+ }
-+ else if (strcmp (line, "CVSServerRunAsUser") == 0)
-+ {
-+ if (cvs_server_run_as != NULL)
-+ free (cvs_server_run_as);
-+ cvs_server_run_as = xstrdup (p);
-+ }
-+
-+ }
-+
-+ if (ferror (fp_info))
-+ {
-+ error (0, errno, "cannot read %s", infopath);
-+ goto error_return;
-+ }
-+ if (fclose (fp_info) < 0)
-+ {
-+ error (0, errno, "cannot close %s", infopath);
-+ goto error_return;
-+ }
-+ free (infopath);
-+ if (line != NULL)
-+ free (line);
-+ return 0;
-+
-+ error_return:
-+ if (infopath != NULL)
-+ free (infopath);
-+ if (line != NULL)
-+ free (line);
-+ return -1;
-+}
-+
-diff -urN cvs-1.11.19.orig/src/patch.c cvs-1.11.19/src/patch.c
---- cvs-1.11.19.orig/src/patch.c 2005-01-31 23:15:02.000000000 +0100
-+++ cvs-1.11.19/src/patch.c 2005-03-14 19:55:09.000000000 +0100
-@@ -503,6 +503,43 @@
- goto out2;
- }
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (rev1)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, rev1, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+ if (rev2)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, rev2, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+ }
-+#endif
-+
- /* Create 3 empty files. I'm not really sure there is any advantage
- * to doing so now rather than just waiting until later.
- *
-diff -urN cvs-1.11.19.orig/src/remove.c cvs-1.11.19/src/remove.c
---- cvs-1.11.19.orig/src/remove.c 2005-01-31 23:15:31.000000000 +0100
-+++ cvs-1.11.19/src/remove.c 2005-03-14 19:55:09.000000000 +0100
-@@ -255,6 +255,25 @@
- {
- char *fname;
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 7,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- /* Re-register it with a negative version number. */
- fname = xmalloc (strlen (vers->vn_user) + 5);
- (void) strcpy (fname, "-");
-diff -urN cvs-1.11.19.orig/src/server.c cvs-1.11.19/src/server.c
---- cvs-1.11.19.orig/src/server.c 2005-03-14 19:49:29.000000000 +0100
-+++ cvs-1.11.19/src/server.c 2005-03-14 19:55:09.000000000 +0100
-@@ -773,6 +773,10 @@
- nothing. But for rsh, we need to do it now. */
- parse_config (current_parsed_root->directory);
-
-+ /* cvsacl patch */
-+ parse_aclconfig (current_parsed_root->directory);
-+
-+
- path = xmalloc (strlen (current_parsed_root->directory)
- + sizeof (CVSROOTADM)
- + 2);
-@@ -3761,6 +3765,23 @@
- do_cvs_command ("rlog", cvslog);
- }
-
-+/* cvsacl patch */
-+static void
-+serve_acl (arg)
-+ char *arg;
-+{
-+ do_cvs_command ("acl", cvsacl);
-+}
-+
-+/* cvsacl patch */
-+static void
-+serve_racl (arg)
-+ char *arg;
-+{
-+ cvs_cmd_name = "racl";
-+ do_cvs_command ("racl", cvsacl);
-+}
-+
- static void
- serve_add (arg)
- char *arg;
-@@ -4821,6 +4842,11 @@
- REQ_LINE("diff", serve_diff, 0),
- REQ_LINE("log", serve_log, 0),
- REQ_LINE("rlog", serve_rlog, 0),
-+
-+ /* cvsacl patch */
-+ REQ_LINE("acl", serve_acl, 0),
-+ REQ_LINE("racl", serve_racl, 0),
-+
- REQ_LINE("add", serve_add, 0),
- REQ_LINE("remove", serve_remove, 0),
- REQ_LINE("update-patches", serve_ignore, 0),
-@@ -5294,6 +5320,10 @@
- {
- struct passwd *pw;
-
-+ /* cvsacl patch */
-+ if (use_cvs_acl && cvs_server_run_as)
-+ username = cvs_server_run_as;
-+
- pw = getpwnam (username);
- if (pw == NULL)
- {
-@@ -5876,6 +5906,9 @@
- in a new CVSROOT/config file to fix the broken one! */
- parse_config (repository);
-
-+ /* cvsacl patch */
-+ parse_aclconfig (repository);
-+
- /* We need the real cleartext before we hash it. */
- descrambled_password = descramble (password);
- host_user = check_password (username, descrambled_password, repository);
-diff -urN cvs-1.11.19.orig/src/status.c cvs-1.11.19/src/status.c
---- cvs-1.11.19.orig/src/status.c 2005-01-31 23:17:28.000000000 +0100
-+++ cvs-1.11.19/src/status.c 2005-03-14 19:55:09.000000000 +0100
-@@ -133,7 +133,27 @@
-
- status = Classify_File (finfo, (char *) NULL, (char *) NULL, (char *) NULL,
- 1, 0, &vers, 0);
-- sstat = "Classify Error";
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
-+ sstat = "Classify Error";
- switch (status)
- {
- case T_UNKNOWN:
-diff -urN cvs-1.11.19.orig/src/tag.c cvs-1.11.19/src/tag.c
---- cvs-1.11.19.orig/src/tag.c 2005-01-31 23:17:45.000000000 +0100
-+++ cvs-1.11.19/src/tag.c 2005-03-14 19:55:09.000000000 +0100
-@@ -665,6 +665,25 @@
- * correctly without breaking your link!
- */
-
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, numtag, 4,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- if (delete_flag)
- return (rtag_delete (rcsfile));
-
-@@ -885,6 +904,21 @@
- if (nversion == NULL)
- goto free_vars_and_return;
- }
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 4,
-+ NULL, NULL, 1))
-+ {
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+ return (0);
-+ }
-+ }
-+#endif
-+
- if (delete_flag)
- {
-
-diff -urN cvs-1.11.19.orig/src/update.c cvs-1.11.19/src/update.c
---- cvs-1.11.19.orig/src/update.c 2005-01-31 23:18:01.000000000 +0100
-+++ cvs-1.11.19/src/update.c 2005-03-14 19:55:09.000000000 +0100
-@@ -601,6 +601,26 @@
- status = Classify_File (finfo, tag, date, options, force_tag_match,
- aflag, &vers, pipeout);
-
-+
-+/* cvsacl patch */
-+#ifdef SERVER_SUPPORT
-+ if (use_cvs_acl && server_active)
-+ {
-+ if (!access_allowed (finfo->file, finfo->repository, vers->tag, 5,
-+ NULL, NULL, 1))
-+ {
-+ if (stop_at_first_permission_denied)
-+ error (1, 0, "permission denied for %s",
-+ Short_Repository (finfo->repository));
-+ else
-+ error (0, 0, "permission denied for %s/%s",
-+ Short_Repository (finfo->repository), finfo->file);
-+
-+ return (0);
-+ }
-+ }
-+#endif
-+
- /* Keep track of whether TAG is a branch tag.
- Note that if it is a branch tag in some files and a nonbranch tag
- in others, treat it as a nonbranch tag. It is possible that case
-diff -urN cvs-1.11.19.orig/src/version.c cvs-1.11.19/src/version.c
---- cvs-1.11.19.orig/src/version.c 2005-01-31 23:18:34.000000000 +0100
-+++ cvs-1.11.19/src/version.c 2005-03-14 19:55:09.000000000 +0100
-@@ -30,7 +30,8 @@
- #endif
- #endif
-
--
-+/* cvsacl patch */
-+char *aclpatch_string = "with CVSACL Patch 1.2.2 (cvsacl.sourceforge.net)\n";
-
- static const char *const version_usage[] =
- {
-@@ -67,6 +68,8 @@
- released. */
- (void) fputs (PACKAGE_STRING, stdout);
- (void) fputs (config_string, stdout);
-+ /* cvsacl patch */
-+ (void) fputs (aclpatch_string, stdout);
-
- #ifdef CLIENT_SUPPORT
- if (current_parsed_root && current_parsed_root->isremote)