提交 d819e4e6 编写于 作者: J Junio C Hamano

daemon: prepare for multiple services.

This adds an infrastructure to selectively enable and disable
more than one services in git-daemon.  Currently upload-pack
service, which serves the git-fetch-pack and git-peek-remote
clients, is the only service that is defined.
Signed-off-by: NJunio C Hamano <junkio@cox.net>
上级 370e0966
......@@ -232,13 +232,42 @@ static char *path_ok(char *dir)
return NULL; /* Fallthrough. Deny by default */
}
static int upload(char *dir)
typedef int (*daemon_service_fn)(void);
struct daemon_service {
const char *name;
const char *config_name;
daemon_service_fn fn;
int enabled;
int overridable;
};
static struct daemon_service *service_looking_at;
static int service_enabled;
static int git_daemon_config(const char *var, const char *value)
{
if (!strncmp(var, "daemon.", 7) &&
!strcmp(var + 7, service_looking_at->config_name)) {
service_enabled = git_config_bool(var, value);
return 0;
}
/* we are not interested in parsing any other configuration here */
return 0;
}
static int run_service(char *dir, struct daemon_service *service)
{
/* Timeout as string */
char timeout_buf[64];
const char *path;
int enabled = service->enabled;
loginfo("Request %s for '%s'", service->name, dir);
loginfo("Request for '%s'", dir);
if (!enabled && !service->overridable) {
logerror("'%s': service not enabled.", service->name);
errno = EACCES;
return -1;
}
if (!(path = path_ok(dir)))
return -1;
......@@ -260,12 +289,34 @@ static int upload(char *dir)
return -1;
}
if (service->overridable) {
service_looking_at = service;
service_enabled = -1;
git_config(git_daemon_config);
if (0 <= service_enabled)
enabled = service_enabled;
}
if (!enabled) {
logerror("'%s': service not enabled for '%s'",
service->name, path);
errno = EACCES;
return -1;
}
/*
* We'll ignore SIGTERM from now on, we have a
* good client.
*/
signal(SIGTERM, SIG_IGN);
return service->fn();
}
static int upload_pack(void)
{
/* Timeout as string */
char timeout_buf[64];
snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
/* git-upload-pack only ever reads stuff, so this is safe */
......@@ -273,10 +324,36 @@ static int upload(char *dir)
return -1;
}
static struct daemon_service daemon_service[] = {
{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
};
static void enable_service(const char *name, int ena) {
int i;
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
if (!strcmp(daemon_service[i].name, name)) {
daemon_service[i].enabled = ena;
return;
}
}
die("No such service %s", name);
}
static void make_service_overridable(const char *name, int ena) {
int i;
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
if (!strcmp(daemon_service[i].name, name)) {
daemon_service[i].overridable = ena;
return;
}
}
die("No such service %s", name);
}
static int execute(struct sockaddr *addr)
{
static char line[1000];
int pktlen, len;
int pktlen, len, i;
if (addr) {
char addrbuf[256] = "";
......@@ -313,8 +390,14 @@ static int execute(struct sockaddr *addr)
if (len && line[len-1] == '\n')
line[--len] = 0;
if (!strncmp("git-upload-pack ", line, 16))
return upload(line+16);
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
struct daemon_service *s = &(daemon_service[i]);
int namelen = strlen(s->name);
if (!strncmp("git-", line, 4) &&
!strncmp(s->name, line + 4, namelen) &&
line[namelen + 4] == ' ')
return run_service(line + namelen + 5, s);
}
logerror("Protocol error: '%s'", line);
return -1;
......@@ -805,6 +888,22 @@ int main(int argc, char **argv)
group_name = arg + 8;
continue;
}
if (!strncmp(arg, "--enable=", 9)) {
enable_service(arg + 9, 1);
continue;
}
if (!strncmp(arg, "--disable=", 10)) {
enable_service(arg + 10, 0);
continue;
}
if (!strncmp(arg, "--enable-override=", 18)) {
make_service_overridable(arg + 18, 1);
continue;
}
if (!strncmp(arg, "--disable-override=", 19)) {
make_service_overridable(arg + 19, 0);
continue;
}
if (!strcmp(arg, "--")) {
ok_paths = &argv[i+1];
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册