]> oss.titaniummirror.com Git - repo_shell.git/commitdiff
Add extended wildcard matching 0.4
authorR. Steve McKown <rsmckown@gmail.com>
Fri, 28 Sep 2012 05:49:25 +0000 (23:49 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Fri, 28 Sep 2012 05:49:25 +0000 (23:49 -0600)
Now '*' can be used as the last character of a userid or repoid target.
Such as:

[user_groups]
group = st* sm*

[repo_groups]
rgroup = mirrors/*

[repo oss*]
* = rw

Makefile
git_acl.c
git_acl.cfg.example
match.c [new file with mode: 0644]
match.h [new file with mode: 0644]
repo_shell.c
stra.c
stra.h

index 49f7334e9cc1aafb6ce9fabf305f3d167f3626c0..eb4728c21f171ab10bc51fee06ffe4846f193802 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -15,13 +15,13 @@ PROGRAMS = $(MAIN) mystrtok_test acl_test
 
 all: $(MAIN)
 
-repo_shell: repo_shell.c inih/ini.c git_acl.c mystrtok.c stra.c utility.c version.c
+repo_shell: repo_shell.c inih/ini.c git_acl.c mystrtok.c stra.c utility.c match.c version.c
        $(CC) -I inih $^ -o $@
 
 mystrtok_test: mystrtok_test.c mystrtok.c utility.c
        $(CC) -g $^ -o $@
 
-acl_test: acl_test.c git_acl.c inih/ini.c mystrtok.c stra.c utility.c
+acl_test: acl_test.c git_acl.c inih/ini.c mystrtok.c stra.c utility.c match.c
        $(CC) -I inih $^ -o $@
 
 $(INFILES):%: %.in
index ea171feedf2ba521cf9cf9995961e3b4769cacdf..4bb75ee46fe715788da76b44ae6415db956ffbf7 100644 (file)
--- a/git_acl.c
+++ b/git_acl.c
 #include "utility.h"
 #include "mystrtok.h"
 #include "stra.h"
+#include "match.h"
 #include "git_acl.h"
 
-#define ANYID   "*"
-
 enum {
   DFLT_IDS_SZ = 32
 };
@@ -123,7 +122,7 @@ static bool str_has_word(const char* string, const char* word)
   char *p = my_strtok(&s, " \t\n");
 
   while (p) {
-    if (!strcmp(p, word) || !strcmp(p, ANYID)) {
+    if (match(p, word)) {
       free(_s);
       return true;
     }
@@ -161,8 +160,8 @@ static int acl_handler(void* user, const char* section, const char* name,
     if (!repo || my_strtok(&p, " \t\n"))
       die("acl_handler: badly formatted section '%s'", section);
     /* repo is repo name, name is userid, value is permission */
-    if ((!strcmp(repo, ANYID) || stra_find(&acl->repoids, repo) >= 0) &&
-        (!strcmp(name, ANYID) || stra_find(&acl->userids, name) >= 0)) {
+    if (stra_match(&acl->repoids, repo) >= 0 &&
+        stra_match(&acl->userids, name) >= 0) {
       acl->perms = perms_from_str(value);
       set_lm_repoid(repo);
       set_lm_userid(name);
index 0ff90152ff2e40977f23b157a02e9bfef3ed0d10..9804b1e007dc7f44b03e45496178ef8a8776c556 100644 (file)
@@ -32,9 +32,17 @@ qa = frank bill
 allusers = *
 
 [repo_groups]
+mirrors = mirror/*
 public = oss-web.git repo_shell.git cp210x.git
 private = redmine.git nesc.git
 
+[repo oss*]
+steve = rw
+
+[repo mirrors]
+jobu=rw
+devs=r
+
 [repo nesc.git]
 steve = r
 devs = rw
diff --git a/match.c b/match.c
new file mode 100644 (file)
index 0000000..32938a1
--- /dev/null
+++ b/match.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright © 2012, Titanium Mirror, Inc.
+ * All Rights Reserved.
+ *
+ * This document is the proprietary and confidential property of
+ * Titanium Mirror, Inc.  All use, distribution, reproduction or re-distribution
+ * is disallowed without the prior express written consent of
+ * Titanium Mirror, Inc.
+ */
+
+/*
+ * Match allowing wildcard ('*')
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#include <stdbool.h>
+#include <string.h>
+
+bool match(const char* pattern, const char* string)
+{
+  char* p;
+
+  if (!pattern || !string)
+    return false;
+  p = index(pattern, '*');
+  if (p == pattern)
+    return true;
+  else if (p)
+    return (strncmp(pattern, string, p - pattern) == 0);
+  else
+    return (strcmp(pattern, string) == 0);
+}
diff --git a/match.h b/match.h
new file mode 100644 (file)
index 0000000..756d6c6
--- /dev/null
+++ b/match.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright © 2012, Titanium Mirror, Inc.
+ * All Rights Reserved.
+ *
+ * This document is the proprietary and confidential property of
+ * Titanium Mirror, Inc.  All use, distribution, reproduction or re-distribution
+ * is disallowed without the prior express written consent of
+ * Titanium Mirror, Inc.
+ */
+
+/*
+ * Match allowing wildcard ('*')
+ *
+ * @author R. Steve McKown <rsmckown@gmail.com>
+ */
+
+#ifndef MATCH_H
+#define MATCH_H
+
+#include <stdbool.h>
+
+bool match(const char* pattern, const char* string);
+
+#endif /* end of include guard: MATCH_H */
index dc9b8d611e6aa808c7a369671fa3b2784f15295e..660c2fd282685927cf53e11e9a049eb14570261f 100644 (file)
@@ -216,31 +216,36 @@ int main(int argc, char **argv)
     return 0;
   }
 
-  prog = xstrdup(argv[2]);
-  if (!strncmp(prog, "git", 3) && isspace(prog[3]))
-    /* Accept "git foo" as if the caller said "git-foo". */
-    prog[3] = '-';
-
-  for (cmd = cmd_list ; cmd->name ; cmd++) {
-    int len = strlen(cmd->name);
-    char *arg;
-    struct passwd *pw;
-    if (strncmp(cmd->name, prog, len))
-      continue;
-    arg = NULL;
-    switch (prog[len]) {
-    case '\0':
+  if (argc == 3) {
+    /* argv[0] = repo_shell, argv[1] = -c, argv[2] = cmd
+     * cmd = "svnserve -t" or "git-xxx '/path/to/repo.git'"
+     */
+    prog = xstrdup(argv[2]);
+    if (!strncmp(prog, "git", 3) && isspace(prog[3]))
+      /* Accept "git foo" as if the caller said "git-foo". */
+      prog[3] = '-';
+
+    for (cmd = cmd_list ; cmd->name ; cmd++) {
+      int len = strlen(cmd->name);
+      char *arg;
+      struct passwd *pw;
+      if (strncmp(cmd->name, prog, len))
+        continue;
       arg = NULL;
-      break;
-    case ' ':
-      arg = prog + len + 1;
-      break;
-    default:
-      continue;
+      switch (prog[len]) {
+        case '\0':
+          arg = NULL;
+          break;
+        case ' ':
+          arg = prog + len + 1;
+          break;
+        default:
+          continue;
+      }
+
+      pw = getpwuid(getuid());
+      exit(cmd->exec(cmd->name, arg, pw->pw_name));
     }
-
-    pw = getpwuid(getuid());
-    exit(cmd->exec(cmd->name, arg, pw->pw_name));
   }
 
   if (!check_ssh_interactive(getuid()))
diff --git a/stra.c b/stra.c
index 4e2f04b8395075c8fd6d978b99fb3f1ee0437003..232419af91fe7a39d9a6ec977147fd3629d44f36 100644 (file)
--- a/stra.c
+++ b/stra.c
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include "utility.h"
 #include "stra.h"
+#include "match.h"
 
 void stra_init(stra_t *stra, size_t size)
 {
@@ -61,6 +62,21 @@ int stra_add(stra_t *stra, const char *item)
   return stra->count++;
 }
 
+int stra_match(stra_t *stra, const char *item)
+{
+  unsigned i;
+
+  if (!stra)
+    die("stra_in: stra NULL reference");
+  if (!item)
+    die("stra_in: item is NULL");
+  for (i = 0; i < stra->count; i++) {
+    if (match(item, stra->items[i]))
+      return i;
+  }
+  return -1;
+}
+
 int stra_find(stra_t *stra, const char *item)
 {
   unsigned i;
diff --git a/stra.h b/stra.h
index a2f43d61a5ac6def5f5e814d89413c71ec783cee..fad9501e21a68aa1c71173b04548dd3a7ab15947 100644 (file)
--- a/stra.h
+++ b/stra.h
@@ -37,6 +37,9 @@ void stra_destroy(stra_t *stra);
 /* Add an item to the end of the string array, returning its ele# */
 int stra_add(stra_t *stra, const char *item);
 
+/* Return the ele# of the first string matching item, which may have * */
+int stra_match(stra_t *stra, const char *item);
+
 /* Return the ele# of the first string matching item */
 int stra_find(stra_t *stra, const char *item);