From d87bba846d368e560193a1f75de6d66bffe986cf Mon Sep 17 00:00:00 2001 From: Ferry Huberts Date: Wed, 23 Mar 2011 11:57:42 +0100 Subject: cgit_open_filter: also take the repo as a parameter To prepare for handing repo configuration to the filter script that is executed. Signed-off-by: Ferry Huberts Signed-off-by: Lars Hjemli --- shared.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared.c') diff --git a/shared.c b/shared.c index 7ec2e19..e4879df 100644 --- a/shared.c +++ b/shared.c @@ -376,7 +376,7 @@ int cgit_parse_snapshots_mask(const char *str) return rv; } -int cgit_open_filter(struct cgit_filter *filter) +int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) { filter->old_stdout = chk_positive(dup(STDOUT_FILENO), -- cgit v1.2.3-70-g09d2 From 14f28923a2ed31fba9bf7042e8e2dff21717c333 Mon Sep 17 00:00:00 2001 From: Ferry Huberts Date: Wed, 23 Mar 2011 11:57:43 +0100 Subject: cgit_open_filter: hand down repo configuration to script The environment variables can be used to (for example) resolve the following situation: Suppose a server setup in which each repository has a trac instance; the commit filter needs to know with which repository it's dealing in order to be able to resolve the #123 ticket numbers in the commit messages into hyperlinks into the correct trac instance. Signed-off-by: Ferry Huberts Signed-off-by: Lars Hjemli --- shared.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) (limited to 'shared.c') diff --git a/shared.c b/shared.c index e4879df..8c3d18a 100644 --- a/shared.c +++ b/shared.c @@ -7,6 +7,8 @@ */ #include "cgit.h" +#include +#include struct cgit_repolist cgit_repolist; struct cgit_context ctx; @@ -376,6 +378,70 @@ int cgit_parse_snapshots_mask(const char *str) return rv; } +typedef struct { + char * name; + char * value; +} cgit_env_var; + +static char * prepare_env(struct cgit_repo * repo) { + cgit_env_var env_vars[] = { + { .name = "CGIT_REPO_URL", .value = repo->url }, + { .name = "CGIT_REPO_NAME", .value = repo->name }, + { .name = "CGIT_REPO_PATH", .value = repo->path }, + { .name = "CGIT_REPO_OWNER", .value = repo->owner }, + { .name = "CGIT_REPO_DEFBRANCH", .value = repo->defbranch }, + { .name = "CGIT_REPO_SECTION", .value = repo->section }, + { .name = "CGIT_REPO_CLONE_URL", .value = repo->clone_url } + }; + int env_var_count = ARRAY_SIZE(env_vars); + long values_space = (env_var_count * (PATH_MAX + 64)); + + void * buffer; + char ** vars; + char * values; + int vars_index = 0; + unsigned int chars_printed; + + /* Allocate buffer for environment variables: first in the buffer is an + * array of pointers to argument strings, terminated with a NULL pointer. + * After that the argument strings are placed after each other */ + buffer = malloc(((env_var_count + 1) * sizeof(char *)) + values_space); + if (!buffer) + return NULL; + + vars = buffer; + values = (char *) &vars[env_var_count + 1]; + + /* loop over all defined environment variables and their values */ + while (vars_index < env_var_count) { + char * name = env_vars[vars_index].name; + char * value = env_vars[vars_index].value; + + if (!value) + value = ""; + + chars_printed = snprintf(values, (values_space - 1), "%s=%s", name, + value); + if (chars_printed > (values_space - 1)) { + /* Buffer space exhausted: stop adding variables. + * Not all environment variables are defined, but the best we can + * do is to provide the ones that _are_ defined */ + break; + } + + values[chars_printed] = '\0'; + *&vars[vars_index] = values; + values += (chars_printed + 1); + values_space -= (chars_printed + 1); + vars_index++; + } + + /* terminate the array with pointers */ + *&vars[vars_index] = NULL; + + return (char *) buffer; +} + int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) { @@ -384,10 +450,20 @@ int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); if (filter->pid == 0) { + char * env = NULL; + close(filter->pipe_fh[1]); chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), "Unable to use pipe as STDIN"); - execvp(filter->cmd, filter->argv); + + if (repo) + env = prepare_env(repo); + + execve(filter->cmd, filter->argv, (char **)env); + + if (env) + free(env); + die("Unable to exec subprocess %s: %s (%d)", filter->cmd, strerror(errno), errno); } -- cgit v1.2.3-70-g09d2 From c2b58ed8539fcfa4f05cc9da316bbc782f4b8f10 Mon Sep 17 00:00:00 2001 From: Lars Hjemli Date: Sat, 26 Mar 2011 11:22:35 +0100 Subject: shared.c: use execvp() to execute filter commands This reintroduces the use of execvp(), since the filter commands doesn't always contain an absolute path (i.e. snapshot compression filters). Signed-off-by: Lars Hjemli --- shared.c | 68 +++++++++++----------------------------------------------------- 1 file changed, 11 insertions(+), 57 deletions(-) (limited to 'shared.c') diff --git a/shared.c b/shared.c index 8c3d18a..986f965 100644 --- a/shared.c +++ b/shared.c @@ -383,7 +383,7 @@ typedef struct { char * value; } cgit_env_var; -static char * prepare_env(struct cgit_repo * repo) { +static void prepare_env(struct cgit_repo * repo) { cgit_env_var env_vars[] = { { .name = "CGIT_REPO_URL", .value = repo->url }, { .name = "CGIT_REPO_NAME", .value = repo->name }, @@ -394,52 +394,14 @@ static char * prepare_env(struct cgit_repo * repo) { { .name = "CGIT_REPO_CLONE_URL", .value = repo->clone_url } }; int env_var_count = ARRAY_SIZE(env_vars); - long values_space = (env_var_count * (PATH_MAX + 64)); - - void * buffer; - char ** vars; - char * values; - int vars_index = 0; - unsigned int chars_printed; - - /* Allocate buffer for environment variables: first in the buffer is an - * array of pointers to argument strings, terminated with a NULL pointer. - * After that the argument strings are placed after each other */ - buffer = malloc(((env_var_count + 1) * sizeof(char *)) + values_space); - if (!buffer) - return NULL; - - vars = buffer; - values = (char *) &vars[env_var_count + 1]; - - /* loop over all defined environment variables and their values */ - while (vars_index < env_var_count) { - char * name = env_vars[vars_index].name; - char * value = env_vars[vars_index].value; - - if (!value) - value = ""; - - chars_printed = snprintf(values, (values_space - 1), "%s=%s", name, - value); - if (chars_printed > (values_space - 1)) { - /* Buffer space exhausted: stop adding variables. - * Not all environment variables are defined, but the best we can - * do is to provide the ones that _are_ defined */ - break; - } - - values[chars_printed] = '\0'; - *&vars[vars_index] = values; - values += (chars_printed + 1); - values_space -= (chars_printed + 1); - vars_index++; - } - - /* terminate the array with pointers */ - *&vars[vars_index] = NULL; - - return (char *) buffer; + cgit_env_var *p, *q; + static char *warn = "cgit warning: failed to set env: %s=%s\n"; + + p = env_vars; + q = p + env_var_count; + for (; p < q; p++) + if (setenv(p->name, p->value, 1)) + fprintf(stderr, warn, p->name, p->value); } int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) @@ -450,20 +412,12 @@ int cgit_open_filter(struct cgit_filter *filter, struct cgit_repo * repo) chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); if (filter->pid == 0) { - char * env = NULL; - close(filter->pipe_fh[1]); chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), "Unable to use pipe as STDIN"); - if (repo) - env = prepare_env(repo); - - execve(filter->cmd, filter->argv, (char **)env); - - if (env) - free(env); - + prepare_env(repo); + execvp(filter->cmd, filter->argv); die("Unable to exec subprocess %s: %s (%d)", filter->cmd, strerror(errno), errno); } -- cgit v1.2.3-70-g09d2