svn commit: r240538 - svnadmin/tools/checkacl
Bjoern A. Zeeb
bz at FreeBSD.org
Sat Sep 15 19:17:20 UTC 2012
Author: bz
Date: Sat Sep 15 19:17:19 2012
New Revision: 240538
URL: http://svn.freebsd.org/changeset/base/240538
Log:
Start synchronizing checkacl.c between various SVN repositories.
Stop using CVS access files and use the SVN versions.
Use a defined length for user named (not ideal but better than 32).
Rather than using a variable per repo and karma, use two bitfields.
Factor out repeated tasks, as checking an access file and adding
the string for another foreign commit bit.
Use #ifdef checks for all files, not just docs and ports. base is
not special.
Defer variable initialization to when needed.
Accept a mandatory argument, the repo name, to allow code sharing
between the repositories of all shared access files.
Consistently use the 'username' and not pw_name after copy; close
the password database to avoid further access.
Inspired by: ports version from beat
Modified:
svnadmin/tools/checkacl/checkacl.c
Modified: svnadmin/tools/checkacl/checkacl.c
==============================================================================
--- svnadmin/tools/checkacl/checkacl.c Sat Sep 15 18:53:00 2012 (r240537)
+++ svnadmin/tools/checkacl/checkacl.c Sat Sep 15 19:17:19 2012 (r240538)
@@ -4,6 +4,8 @@
* FreeBSD Subversion tree ACL check helper. The program looks in
* relevant access files to find out if the committer may commit.
*
+ * !!! Please keep in sync between various SVN repositories. !!!
+ *
* From: Id: cvssh.c,v 1.38 2008/05/31 02:54:58 peter Exp
* $FreeBSD$
*/
@@ -24,13 +26,16 @@
#include <stdarg.h>
#include <fcntl.h>
-#define ACCESS "/s/svn/base/conf/access"
-#define DOCACCESS "/home/dcvs/CVSROOT/access"
-#define PORTSACCESS "/home/pcvs/CVSROOT/access"
-
+#define BASE 0x01
+#define DOC 0x02
+#define PORTS 0x04
+
+#define SVNROOT "/s/svn"
+#define BASEACCESS SVNROOT "/base/conf/access"
+#define DOCACCESS SVNROOT "/doc/conf/access"
+#define PORTSACCESS SVNROOT "/ports/conf/access"
-static char username[32];
-static char committag[256];
+static char username[_SC_LOGIN_NAME_MAX + 1];
static void
msg(const char *fmt, ...)
@@ -43,12 +48,12 @@ msg(const char *fmt, ...)
va_end(ap);
}
-static int
-karmacheck(FILE *fp, char *name)
+static u_int
+karmacheck(FILE *fp, const char *name, u_int k)
{
char buf[1024];
char *p, *s;
- int karma;
+ u_int karma;
karma = 0;
while ((p = fgets(buf, sizeof(buf) - 1, fp)) != NULL) {
@@ -58,11 +63,11 @@ karmacheck(FILE *fp, char *name)
if (*s == '#' || *s == '/' || *s == ';')
break; /* comment */
if (strcmp(s, "*") == 0) { /* all */
- karma++;
+ karma |= k;
break;
}
if (strcmp(s, name) == 0) {
- karma++;
+ karma |= k;
break;
}
break; /* ignore further tokens on line */
@@ -71,34 +76,49 @@ karmacheck(FILE *fp, char *name)
return karma;
}
+static u_int
+read_access(const char *accessf, const u_int repo, u_int k,
+ const char *name)
+{
+ FILE *fp;
+ u_int karma;
+
+ karma = 0;
+ fp = fopen(accessf, "r");
+ if (fp == NULL && (repo & k) == k) {
+ msg("Cannot open %s", accessf);
+ exit(1);
+ } else if (fp != NULL) {
+ karma |= karmacheck(fp, name, k);
+ fclose(fp);
+ }
+
+ return (karma);
+}
+
+static void
+catcommittag(char *committag, const char **comma, const u_int karma,
+ const u_int k, const char *s)
+{
+
+ if ((karma & k) == 0)
+ return;
+
+ strcat(committag, *comma);
+ strcat(committag, s);
+ *comma = ",";
+}
+
int
main(int argc, char *argv[])
{
struct passwd *pw;
struct stat st;
- FILE *fp;
- int i;
gid_t repogid;
gid_t mygroups[NGROUPS_MAX];
- int ngroups;
- int writeable;
- int karma;
-#ifdef PORTSACCESS
- int portskarma;
-#endif
-#ifdef DOCACCESS
- int dockarma;
-#endif
- const char *comma;
+ int i, ngroups, writeable;
+ u_int karma, repo;
-#ifdef PORTSACCESS
- portskarma = 0;
-#endif
-#ifdef DOCACCESS
- dockarma = 0;
-#endif
- karma = 0;
- writeable = 0;
pw = getpwuid(getuid());
if (pw == NULL) {
msg("no user for uid %d", getuid());
@@ -109,11 +129,12 @@ main(int argc, char *argv[])
exit(1);
}
- /* save in a static buffer */
+ /* Save in a static buffer. */
strlcpy(username, pw->pw_name, sizeof(username));
+ endpwent();
- if (stat("/s/svn", &st) < 0) {
- msg("Cannot stat %s", "/s/svn");
+ if (stat(SVNROOT, &st) < 0) {
+ msg("Cannot stat %s", SVNROOT);
exit(1);
}
repogid = st.st_gid;
@@ -121,6 +142,7 @@ main(int argc, char *argv[])
msg("unsafe repo gid %d\n", repogid);
exit(1);
}
+ writeable = 0;
ngroups = getgroups(NGROUPS_MAX, mygroups);
if (ngroups > 0) {
for (i = 0; i < ngroups; i++)
@@ -130,54 +152,48 @@ main(int argc, char *argv[])
if (!writeable)
printf("export SVN_READONLY=y\n");
- fp = fopen(ACCESS, "r");
- if (fp == NULL) {
- msg("Cannot open %s", ACCESS);
+ if (argc != 2) {
+ msg("No repository given");
exit(1);
- } else {
- karma += karmacheck(fp, pw->pw_name);
- fclose(fp);
}
-#ifdef DOCACCESS
- if (karma == 0 && (fp = fopen(DOCACCESS, "r")) != NULL) {
- dockarma += karmacheck(fp, pw->pw_name);
- fclose(fp);
- }
-#endif
-#ifdef PORTSACCESS
- if (karma == 0 && (fp = fopen(PORTSACCESS, "r")) != NULL) {
- portskarma += karmacheck(fp, pw->pw_name);
- fclose(fp);
+ repo = 0;
+ /* Forward compat for base. */
+ if (strcmp(argv[1], "base") == 0 || strcmp(argv[1], "src") == 0)
+ repo |= BASE;
+ else if (strcmp(argv[1], "doc") == 0)
+ repo |= DOC;
+ else if (strcmp(argv[1], "ports") == 0)
+ repo |= PORTS;
+ else {
+ msg("Invalid repository given: %s", argv[1]);
+ exit(1);
}
-#endif
- if (karma == 0) {
- strcpy(committag, "SVN_COMMIT_ATTRIB=");
- comma = "";
+ karma = 0;
+#ifdef BASEACCESS
+ karma |= read_access(BASEACCESS, repo, BASE, username);
+#endif
#ifdef DOCACCESS
- if (dockarma > 0) {
- strcat(committag, comma);
- strcat(committag, "doc");
- comma = ",";
- karma += dockarma;
- }
+ karma |= read_access(DOCACCESS, repo, DOC, username);
#endif
#ifdef PORTSACCESS
- if (portskarma > 0) {
- strcat(committag, comma);
- strcat(committag, "ports");
- comma = ",";
- karma += portskarma;
- }
+ karma |= read_access(PORTSACCESS, repo, PORTS, username);
#endif
- if (karma != 0) {
- printf("export %s\n", committag);
- }
- }
-
if (karma == 0) {
/* If still zero, its a readonly access */
printf("export SVN_READONLY=y\n");
+
+ } else if ((repo & karma) == 0) {
+ char committag[sizeof("src,doc,ports") + 1];
+ const char *comma;
+
+ committag[0] = '\0';
+ comma = "";
+ catcommittag(committag, &comma, karma, BASE, "src");
+ catcommittag(committag, &comma, karma, DOC, "doc");
+ catcommittag(committag, &comma, karma, PORTS, "ports");
+ printf("export SVN_COMMIT_ATTRIB=\"%s\"\n", committag);
}
+
return (0);
}
More information about the svn-src-svnadmin
mailing list