List for cgit developers and users
 help / color / mirror / Atom feed
* [PATCH v3 3/4] cgit_open_filter: hand down repo configuration to script
@ 2011-03-09  9:05 mailings
  0 siblings, 0 replies; 3+ messages in thread
From: mailings @ 2011-03-09  9:05 UTC (permalink / raw)


From: Ferry Huberts <ferry.huberts at pelagic.nl>

Signed-off-by: Ferry Huberts <ferry.huberts at pelagic.nl>
---
 shared.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 1 deletions(-)

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 <stdio.h>
+#include <linux/limits.h>
 
 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);
 	}
-- 
1.7.4





^ permalink raw reply	[flat|nested] 3+ messages in thread
* [PATCH v3 3/4] cgit_open_filter: hand down repo configuration to script
@ 2011-03-09  8:26 mailings
  0 siblings, 0 replies; 3+ messages in thread
From: mailings @ 2011-03-09  8:26 UTC (permalink / raw)


From: Ferry Huberts <ferry.huberts at pelagic.nl>

Signed-off-by: Ferry Huberts <ferry.huberts at pelagic.nl>
---
 shared.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 77 insertions(+), 1 deletions(-)

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 <stdio.h>
+#include <linux/limits.h>
 
 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);
 	}
-- 
1.7.4





^ permalink raw reply	[flat|nested] 3+ messages in thread
* [PATCH v3 0/4] Hand the repo configuration to the filters
@ 2011-03-09  8:13 mailings
  2011-03-09  8:13 ` [PATCH v3 3/4] cgit_open_filter: hand down repo configuration to script mailings
  0 siblings, 1 reply; 3+ messages in thread
From: mailings @ 2011-03-09  8:13 UTC (permalink / raw)


From: Ferry Huberts <ferry.huberts at pelagic.nl>

Changes compared to v2:
- Split out the first 2 patches into a seperate thread
- Incorporated feedback from Lars

Changes compared to v1:
- Rewritten to hand the repo configuration via environment variables


I have a server setup in which each repo has a trac instance and
for the commit filter I really need to know with which repo I'm
dealing in order to be able to resolve the #123 ticket numbers
into hyperlinks into the correct trac instance.

Lars, patch 3 has become quite a bit more complex. However, adding
      environment variables is a matter of simply extending the
      env_vars array in the prepare_env function; only the code
      that processes that array has become a bit more complex.


Ferry Huberts (4):
  new_filter: determine extra_args from filter type
  cgit_open_filter: also take the repo as a parameter
  cgit_open_filter: hand down repo configuration to script
  filters: document environment variables in filter scripts

 cgit.c                         |   27 ++++++++++---
 cgit.h                         |    6 ++-
 cgitrc.5.txt                   |   45 ++++++++++++++++++++--
 filters/commit-links.sh        |   11 +++++
 filters/syntax-highlighting.sh |   11 +++++
 shared.c                       |   80 +++++++++++++++++++++++++++++++++++++++-
 ui-commit.c                    |    6 +-
 ui-repolist.c                  |    2 +-
 ui-snapshot.c                  |    2 +-
 ui-summary.c                   |    2 +-
 ui-tree.c                      |    2 +-
 11 files changed, 172 insertions(+), 22 deletions(-)

-- 
1.7.4





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2011-03-09  9:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-09  9:05 [PATCH v3 3/4] cgit_open_filter: hand down repo configuration to script mailings
  -- strict thread matches above, loose matches on Subject: below --
2011-03-09  8:26 mailings
2011-03-09  8:13 [PATCH v3 0/4] Hand the repo configuration to the filters mailings
2011-03-09  8:13 ` [PATCH v3 3/4] cgit_open_filter: hand down repo configuration to script mailings

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).