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);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to