]> oss.titaniummirror.com Git - repo_shell.git/commitdiff
Allow tools to ref repopath.git as repopath
authorR. Steve McKown <rsmckown@gmail.com>
Fri, 28 Sep 2012 17:42:07 +0000 (11:42 -0600)
committerR. Steve McKown <rsmckown@gmail.com>
Fri, 28 Sep 2012 19:15:57 +0000 (13:15 -0600)
git_acl.c

index 796f5e96bd935b540e23196780b509917b3a658f..3c740dd10a4ac368fae242b0acf7ce41575486d3 100644 (file)
--- a/git_acl.c
+++ b/git_acl.c
@@ -18,6 +18,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include "ini.h"
 #include "utility.h"
 #include "stringutils.h"
@@ -108,6 +109,26 @@ static acl_clear(acl_t *acl)
   stra_destroy(&acl->userids);
 }
 
+/* git tools match /path/to/repo against /path/to/repo.git when the former
+ * doesn't exist and the latter does.  repo_shell addresses this by stripping
+ * the .git prefix off all repopath's read in from .gitacls and the SSH comand
+ * line.  This mimics the expected git tool behavior except when /path/to/repo
+ * and /path/to/repo.git both exist.  This case shouldn't ever be seen anyway.
+ */
+static char *strip_repo(const char *repo_name)
+{
+  if (!repo_name)
+    return NULL;
+  else {
+    char *dot = rindex(repo_name, '.');
+
+    if (dot && !strcmp(dot, ".git"))
+      return xstrndup(repo_name, dot - repo_name);
+    else
+      return xstrdup(repo_name);
+  }
+}
+
 static int acl_handler(void* user, const char* section, const char* name,
     const char* value)
 {
@@ -124,15 +145,18 @@ static int acl_handler(void* user, const char* section, const char* name,
       stra_add(&acl->userids, name);
     }
   } else if (!strcmp(section, "repo_groups")) {
-    if (str_has_word(value, acl->repo)) {
+    char *v = strip_repo(value);
+    if (str_has_word(v, acl->repo)) {
       //debug("repoids += '%s'", name);
       stra_add(&acl->repoids, name);
     }
+    free(v);
   } else if (!strncmp(section, "repo", 4)) {
     char *_p = xstrdup(section + 4);
     char *p = _p;
-    char *repo = my_strtok(&p, " \t\n");
+    char *repo = strip_repo(my_strtok(&p, " \t\n"));
 
+    debug("repo '%s'", repo);
     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 */
@@ -145,6 +169,7 @@ static int acl_handler(void* user, const char* section, const char* name,
       //debug("match: repoid='%s', userid='%s', perms='%s'(%u)", repo, name,
       //    value, acl->perms);
     }
+    free(repo);
     free(_p);
   } else
     die("acl_handler: unknown section='%s' name='%s'", section, name);
@@ -154,6 +179,7 @@ static int acl_handler(void* user, const char* section, const char* name,
 int git_acl(const char *user, const char *repo, const char *file)
 {
   acl_t acl;
+  char *r;
 
   if (!file || !*file || !user || !*user || !repo || !*repo) {
     die("git_acl: invalid args user='%s', repo='%s', file='%s'", user, repo,
@@ -167,7 +193,9 @@ int git_acl(const char *user, const char *repo, const char *file)
   acl.user = (char*)user;
   acl.repo = (char*)repo;
   stra_add(&acl.userids, acl.user);
-  stra_add(&acl.repoids, acl.repo);
+  r = strip_repo(acl.repo);
+  stra_add(&acl.repoids, r);
+  free(r);
 
   //debug("Searching for '%s'@'%s'", acl.user, acl.repo);
   if (ini_parse(file, acl_handler, &acl) < 0)