[4.1] 2765c02 Let vcl_dir and vmod_dir also take colon separated paths.

Lasse Karstensen lkarsten at varnish-software.com
Thu Jan 14 15:15:12 CET 2016


commit 2765c02d6eec7599c2b16ffd76ea28b1a9748c31
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Jan 8 18:51:44 2016 +0000

    Let vcl_dir and vmod_dir also take colon separated paths.

diff --git a/bin/varnishd/mgt/mgt_param_tbl.c b/bin/varnishd/mgt/mgt_param_tbl.c
index 16886b2..59fcfed 100644
--- a/bin/varnishd/mgt/mgt_param_tbl.c
+++ b/bin/varnishd/mgt/mgt_param_tbl.c
@@ -58,14 +58,16 @@ struct parspec mgt_parspec[] = {
 		VCC_CC , NULL },
 	{ "vcl_dir", tweak_string, &mgt_vcl_dir,
 		NULL, NULL,
-		"Directory from which relative VCL filenames (vcl.load and "
-		"include) are opened.",
+		"Directory (or colon separated list of directories) "
+		"from which relative VCL filenames (vcl.load and "
+		"include) are to be found.",
 		0,
 		VARNISH_VCL_DIR,
 		NULL },
 	{ "vmod_dir", tweak_string, &mgt_vmod_dir,
 		NULL, NULL,
-		"Directory where VCL modules are to be found.",
+		"Directory (or colon separated list of directories) "
+		"where VMODs are to be found.",
 		0,
 		VARNISH_VMOD_DIR,
 		NULL },
diff --git a/bin/varnishtest/tests/m00008.vtc b/bin/varnishtest/tests/m00008.vtc
index 232d3c0..833a282 100644
--- a/bin/varnishtest/tests/m00008.vtc
+++ b/bin/varnishtest/tests/m00008.vtc
@@ -13,12 +13,12 @@ varnish v1 -vcl+backend {
 
 varnish v1 -cliok "param.set vcc_unsafe_path off"
 
-varnish v1 -errvcl {'import ... from path ...' not allowed.} {
+varnish v1 -errvcl {'import ... from path ...' is unsafe.} {
 	backend default { .host = "${s1_sock}"; }
 	import ${vmod_std};
 }
 
-varnish v1 -cliok "param.set vmod_dir ${topbuild}/lib/libvmod_std/.libs/"
+varnish v1 -cliok "param.set vmod_dir /nowhere:${topbuild}/lib/libvmod_std/.libs/:/else"
 
 varnish v1 -vcl+backend {
 	import std;
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index aaba4bf..c52dd8d 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -450,22 +450,24 @@ vcc_destroy_source(struct source *sp)
 /*--------------------------------------------------------------------*/
 
 static struct source *
-vcc_file_source(const struct vcp * const vcp, struct vsb *sb, const char *fn)
+vcc_file_source(const struct vcp * const vcp, struct vsb *sb, char *fn)
 {
-	char *f;
+	char *f, *fnp;
 	struct source *sp;
 
 	if (!vcp->unsafe_path && strchr(fn, '/') != NULL) {
 		VSB_printf(sb, "Include path is unsafe '%s'\n", fn);
 		return (NULL);
 	}
-	f = VFIL_readfile(vcp->vcl_dir, fn, NULL);
-	if (f == NULL) {
-		VSB_printf(sb, "Cannot read file '%s': %s\n",
-		    fn, strerror(errno));
+	f = NULL;
+	fnp = fn;
+	if (VFIL_searchpath(vcp->vcl_path, NULL, &f, &fnp) || f == NULL) {
+		VSB_printf(sb, "Cannot read file '%s' (%s)\n",
+		    fnp != NULL ? fnp : fn, strerror(errno));
 		return (NULL);
 	}
-	sp = vcc_new_source(f, NULL, fn);
+	sp = vcc_new_source(f, NULL, fnp);
+	free(fnp);
 	sp->freeit = f;
 	return (sp);
 }
@@ -801,6 +803,7 @@ VCP_VCL_dir(struct vcp *vcp, const char *str)
 
 	CHECK_OBJ_NOTNULL(vcp, VCP_MAGIC);
 	REPLACE(vcp->vcl_dir, str);
+	VFIL_setpath(&vcp->vcl_path, str);
 }
 
 /*--------------------------------------------------------------------
@@ -813,6 +816,7 @@ VCP_VMOD_dir(struct vcp *vcp, const char *str)
 
 	CHECK_OBJ_NOTNULL(vcp, VCP_MAGIC);
 	REPLACE(vcp->vmod_dir, str);
+	VFIL_setpath(&vcp->vmod_path, str);
 }
 
 /*--------------------------------------------------------------------
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 72ff7b7..3feecd3 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -161,7 +161,9 @@ struct vcp {
 
 	char			*builtin_vcl;
 	char			*vcl_dir;
+	struct vfil_path	*vcl_path;
 	char			*vmod_dir;
+	struct vfil_path	*vmod_path;
 	unsigned		err_unref;
 	unsigned		allow_inline_c;
 	unsigned		unsafe_path;
diff --git a/lib/libvcc/vcc_vmod.c b/lib/libvcc/vcc_vmod.c
index d82ad3e..0a165c7 100644
--- a/lib/libvcc/vcc_vmod.c
+++ b/lib/libvcc/vcc_vmod.c
@@ -30,20 +30,39 @@
 
 #include <dlfcn.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 
 #include "vcc_compile.h"
 
 #include "vcs_version.h"
 
+#include "vfil.h"
 #include "vmod_abi.h"
 #include "vrt.h"
 
+static int
+vcc_path_dlopen(void *priv, const char *fn)
+{
+	void *hdl, **pp;
+
+	AN(priv);
+	AN(fn);
+
+fprintf(stderr, "TRY <%s>\n", fn);
+	hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
+	if (hdl == NULL)
+		return (1);
+	pp = priv;
+	*pp = hdl;
+	return (0);
+}
+
 void
 vcc_ParseImport(struct vcc *tl)
 {
 	void *hdl;
-	char fn[1024];
+	char fn[1024], *fnp;
 	char buf[256];
 	struct token *mod, *t1;
 	struct inifin *ifp;
@@ -85,32 +104,33 @@ vcc_ParseImport(struct vcc *tl)
 	sym->def_e = tl->t;
 
 	if (tl->t->tok == ID) {
-		if (!tl->param->unsafe_path) {
-			VSB_printf(tl->sb,
-			    "'import ... from path ...' not allowed.\nAt:");
-			vcc_ErrToken(tl, tl->t);
-			vcc_ErrWhere(tl, tl->t);
-			return;
-		}
 		if (!vcc_IdIs(tl->t, "from")) {
 			VSB_printf(tl->sb, "Expected 'from path ...'\n");
 			vcc_ErrWhere(tl, tl->t);
 			return;
 		}
 		vcc_NextToken(tl);
+		if (!tl->param->unsafe_path && strchr(tl->t->dec, '/')) {
+			VSB_printf(tl->sb,
+			    "'import ... from path ...' is unsafe.\nAt:");
+			vcc_ErrToken(tl, tl->t);
+			vcc_ErrWhere(tl, tl->t);
+			return;
+		}
 		ExpectErr(tl, CSTR);
 		bprintf(fn, "%s", tl->t->dec);
 		vcc_NextToken(tl);
 	} else {
-		bprintf(fn, "%s/libvmod_%.*s.so", tl->param->vmod_dir, PF(mod));
+		bprintf(fn, "libvmod_%.*s.so", PF(mod));
 	}
 
 	SkipToken(tl, ';');
 
-	hdl = dlopen(fn, RTLD_NOW | RTLD_LOCAL);
-	if (hdl == NULL) {
+	fnp = fn;
+	if (VFIL_searchpath(tl->param->vmod_path,
+	    vcc_path_dlopen, &hdl, &fnp)) {
 		VSB_printf(tl->sb, "Could not load VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp != NULL ? fnp : fn);
 		VSB_printf(tl->sb, "\tdlerror: %s\n", dlerror());
 		vcc_ErrWhere(tl, mod);
 		return;
@@ -120,7 +140,7 @@ vcc_ParseImport(struct vcc *tl)
 	vmd = dlsym(hdl, buf);
 	if (vmd == NULL) {
 		VSB_printf(tl->sb, "Malformed VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\t(no Vmod_Data symbol)\n");
 		vcc_ErrWhere(tl, mod);
 		return;
@@ -128,7 +148,7 @@ vcc_ParseImport(struct vcc *tl)
 	if (strcmp(VCS_Branch, "master") == 0 &&
 	    strcmp(vmd->abi, VMOD_ABI_Version) != 0) {
 		VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tABI mismatch, expected <%s>, got <%s>\n",
 			   VMOD_ABI_Version, vmd->abi);
 		vcc_ErrWhere(tl, mod);
@@ -137,7 +157,7 @@ vcc_ParseImport(struct vcc *tl)
 	if (vmd->vrt_major != VRT_MAJOR_VERSION ||
 	    vmd->vrt_minor > VRT_MINOR_VERSION) {
 		VSB_printf(tl->sb, "Incompatible VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tVMOD version %u.%u\n",
 		    vmd->vrt_major, vmd->vrt_minor);
 		VSB_printf(tl->sb, "\tvarnishd version %u.%u\n",
@@ -151,7 +171,7 @@ vcc_ParseImport(struct vcc *tl)
 	    vmd->proto == NULL ||
 	    vmd->abi == NULL) {
 		VSB_printf(tl->sb, "Mangled VMOD %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tInconsistent metadata\n");
 		vcc_ErrWhere(tl, mod);
 		return;
@@ -159,7 +179,7 @@ vcc_ParseImport(struct vcc *tl)
 
 	if (!vcc_IdIs(mod, vmd->name)) {
 		VSB_printf(tl->sb, "Wrong VMOD file %.*s\n", PF(mod));
-		VSB_printf(tl->sb, "\tFile name: %s\n", fn);
+		VSB_printf(tl->sb, "\tFile name: %s\n", fnp);
 		VSB_printf(tl->sb, "\tContains vmod \"%s\"\n", vmd->name);
 		vcc_ErrWhere(tl, mod);
 		return;
@@ -172,7 +192,8 @@ vcc_ParseImport(struct vcc *tl)
 	VSB_printf(ifp->ini, "\t    sizeof(Vmod_%.*s_Func),\n", PF(mod));
 	VSB_printf(ifp->ini, "\t    \"%.*s\",\n", PF(mod));
 	VSB_printf(ifp->ini, "\t    ");
-	EncString(ifp->ini, fn, NULL, 0);
+	EncString(ifp->ini, fnp, NULL, 0);
+	free(fnp);
 	VSB_printf(ifp->ini, ",\n");
 	AN(vmd);
 	AN(vmd->file_id);



More information about the varnish-commit mailing list