Commit Diff


commit - e6ca8eb1561ade7484a0249ffd1234cdf94e2562
commit + 9cc630aa63cfd22553912b5a1fc41a71776cb272
blob - fa5c71c78dd59c163f5e9659ecd939ccc170c3d3
blob + 5437a4c31bec0bfab50d8551aff8644174e17442
--- ChangeLog
+++ ChangeLog
@@ -1,4 +1,6 @@
 2021-04-27  Omar Polo  <op@omarpolo.com>
+
+	* parse.y (servopt): added ``env'' option to define environment vars for CGI scripts
 
 	* log.c (fatal): lower the log priority for fatal errors from CRIT to ERR
 
blob - 73d990edb34b8619d836f0d388751051fb2b5b04
blob + 6437a4233765bbddba92e87c77363406bc53bd58
--- ex.c
+++ ex.c
@@ -136,6 +136,7 @@ launch_cgi(struct iri *iri, struct cgireq *req, struct
 		char *ex, *pwd;
 		char iribuf[GEMINI_URL_LEN];
 		char path[PATH_MAX];
+		struct envlist *e;
 
 		close(p[0]);
 		if (dup2(p[1], 1) == -1)
@@ -200,6 +201,10 @@ launch_cgi(struct iri *iri, struct cgireq *req, struct
 		setenv_time("TLS_CLIENT_NOT_AFTER", req->notafter);
 		setenv_time("TLS_CLIENT_NOT_BEFORE", req->notbefore);
 
+		TAILQ_FOREACH(e, &vhost->env, envs) {
+			safe_setenv(e->name, e->value);
+		}
+
 		strlcpy(path, ex, sizeof(path));
 
 		pwd = dirname(path);
blob - 77473a469b7afc04d6aeaeae3dd3c43f4c93977b
blob + cc42423baf6353a590b8bec86194c47f16650208
--- gmid.1
+++ gmid.1
@@ -241,6 +241,13 @@ is set to
 Handle all the requests for the current virtual host using the
 CGI script at
 .Pa path .
+.It Ic env Ar name Ar value
+Set the environment variable
+.Ar name
+to
+.Ar value
+when executing CGI scripts.
+Can be provided more than once.
 .It Ic index Ar string
 Set the directory index file.
 If not specified, it defaults to
@@ -270,7 +277,7 @@ A
 .Ic location
 section may include most of the server configuration rules
 except
-.Ic cert , Ic key , Ic root , Ic location ,
+.Ic cert , Ic env , Ic key , Ic root , Ic location ,
 .Ic entrypoint No and Ic cgi .
 .It Ic root Pa directory
 Specify the root directory for this server.
blob - ec22fe4c9e865f5bf338a74f5fff64bd0258b4e5
blob + 710067347fa1aeb0c8d66d39101c605712e7b80f
--- gmid.c
+++ gmid.c
@@ -244,6 +244,7 @@ free_config(void)
 {
 	struct vhost *h, *th;
 	struct location *l, *tl;
+	struct envlist *e, *te;
 	int v;
 
 	v = conf.verbose;
@@ -266,6 +267,12 @@ free_config(void)
 			free(l);
 		}
 
+		TAILQ_FOREACH_SAFE(e, &h->env, envs, te) {
+			free(e->name);
+			free(e->value);
+			free(e);
+		}
+
 		TAILQ_REMOVE(&hosts, h, vhosts);
 		free(h);
 	}
blob - 6f4223ececf4a54382efe524370eda3d75537e7f
blob + f29c210e0fa6286fb4f050d78ac5a712650d2c70
--- gmid.h
+++ gmid.h
@@ -73,6 +73,13 @@ struct location {
 	TAILQ_ENTRY(location) locations;
 };
 
+TAILQ_HEAD(envhead, envlist);
+struct envlist {
+	char		*name;
+	char		*value;
+	TAILQ_ENTRY(envlist) envs;
+};
+
 extern TAILQ_HEAD(vhosthead, vhost) hosts;
 struct vhost {
 	const char	*domain;
@@ -89,6 +96,8 @@ struct vhost {
 	 * settings for the vhost, then follows the "real" location
 	 * rules as specified in the configuration. */
 	struct lochead	 locations;
+
+	struct envhead	 env;
 };
 
 struct etm {			/* extension to mime */
blob - d61b9940fb62671e6862fa7949041cf0a5a586e6
blob + e4b5e6d6b14d9c8f435da0e5c5bff3188e6807b1
--- lex.l
+++ lex.l
@@ -60,6 +60,7 @@ chroot		return TCHROOT;
 client		return TCLIENT;
 default		return TDEFAULT;
 entrypoint	return TENTRYPOINT;
+env		return TENV;
 index		return TINDEX;
 ipv6		return TIPV6;
 key		return TKEY;
blob - 0646f137fff423e407a151e744895d056b12169a
blob + df62e818a863060518cbedc4ddf7489bfdac2ff9
--- parse.y
+++ parse.y
@@ -59,7 +59,7 @@ void		 advance_loc(void);
 
 %token TIPV6 TPORT TPROTOCOLS TMIME TDEFAULT TTYPE
 %token TCHROOT TUSER TSERVER TPREFORK
-%token TLOCATION TCERT TKEY TROOT TCGI TLANG TLOG TINDEX TAUTO
+%token TLOCATION TCERT TKEY TROOT TCGI TENV TLANG TLOG TINDEX TAUTO
 %token TSTRIP TBLOCK TRETURN TENTRYPOINT TREQUIRE TCLIENT TCA
 %token TERR
 
@@ -133,6 +133,17 @@ servopt		: TCERT TSTRING		{ host->cert = ensure_absolu
 				memmove($2, $2+1, strlen($2));
 			host->entrypoint = $2;
 		}
+		| TENV TSTRING TSTRING {
+			struct envlist *e;
+
+			e = xcalloc(1, sizeof(*e));
+			e->name = $2;
+			e->value = $3;
+			if (TAILQ_EMPTY(&host->env))
+				TAILQ_INSERT_HEAD(&host->env, e, envs);
+			else
+				TAILQ_INSERT_TAIL(&host->env, e, envs);
+		}
 		| TKEY TSTRING		{ host->key  = ensure_absolute_path($2); }
 		| TROOT TSTRING		{ host->dir  = ensure_absolute_path($2); }
 		| locopt